在一个函数调用中创建一个线程池,并从另一个函数调用中使用它

时间:2015-02-23 01:18:34

标签: c++ multithreading dll threadpool

我有一个Fortran程序,它调用C ++ DLL来对10000组数据进行一些数学运算。数据集完全相互独立。我打算创建一个线程池,然后向它发送任务。但是,对dll的调用将超过1000次(每次调用10000个数据集正在处理中)。

我的问题是:当我在第一次调用dll时创建线程池时,在dll函数返回后该线程池会发生什么?第二次调用(以及剩余的998次调用)是否可以访问第一次调用期间创建的池。

2 个答案:

答案 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;,您也可以使用它而不是创建自己的。