我有一个Fortran程序,它调用C ++ DLL来对10000组数据进行一些数学运算。数据集完全相互独立。我打算创建一个线程池,然后向它发送任务。但是,对dll的调用将超过1000次(每次调用10000个数据集正在处理中)。
我的问题是:当我在第一次调用dll时创建线程池时,在dll函数返回后该线程池会发生什么?第二次调用(以及剩余的998次调用)是否可以访问第一次调用期间创建的池。
答案 0 :(得分:1)
如果你设置正确,你确实可以使用相同的线程池。
在FORTRAN-> C ++调用线程的堆栈上创建的对象将被销毁,因为该堆栈展开并且控制返回到FORTRAN,因此在该堆栈上拥有线程池管理数据不是一个好主意。但是你可以:
new
)从FORTRAN-> C ++调用中分离生命周期。后者可能更简单,更清晰......指向管理线程池的堆对象/数据的指针可以返回到FORTRAN并用作将来调用的“句柄”,表示应该使用相同的线程池。
答案 1 :(得分:1)
如果你可以控制fortran代码,你可以通过使用3个函数而不是一个函数来节省你自己隐藏的状态。
someStateHandle PrepareBackgroundWork();
// Then you do your actual call series...
DoMyMath(someStateHandle, args...);
// And when you are done with all that, you call
FinalizeBackgroundWork(someStateHandle);
如果您无法控制fortran代码,则必须决定要保留的内容(Threadpool内容或线程句柄以及一些同步对象)并懒惰地初始化它们。
struct MyWorkerContext
{
size_t numberOfWorkerThreads;
std::vector<HANDLE> workerHandles;
// ...
};
static MyWorkerContext* s_context = NULL; // Sorry - looks like a singleton to me.
void DoMyMath( args..)
{
if(NULL == s_context) InitializeContext();
if( NULL != s_context )
{
// do the calculations using all that infrastructure.
}
}
E.g. in DLLMain() or hopefully earlier: clean up s_context.
最后,我认为有一个&#34;默认线程池&#34;,您也可以使用它而不是创建自己的。