2013-04-05 44 views
3

我的目标是我在标题中询问的地方,我想调用者线程不会等待子线程创建和恢复时使用std ::线程ctor与线程函数(非空ctors)C++ 11推迟的“线程”创建(即指定线程函数,但不要等待创建物理线程)

当我尝试使用线程函数在DLL加载期间创建一个std ::线程对象时,我的问题点击(在Windows中)。 这是一个问题,因为(就我而言) - 线程构造函数试图创建一个物理线程 - Ctor不知何故(对我来说不幸)等待物理线程恢复(上线) - 不幸的是,Win API的确会如果线程在该函数调用期间创建,则不允许线程在LoadLibrary调用中恢复。 - 所以我有一个死锁:LoadLibrary创建一个线程,它等待它恢复,Windows不会让它恢复。我可以发明一些解决方案来解决这个问题(通过一个独特的线程不使用std ::线程将构造额外的线程(std :: threads),但我然后错过了使用“唯一”std ::线程为我的线程需要:-))。 但是,如果std :: thread被指示不等待物理线程恢复(如果它是使用线程函数(或lambda或其他)构造的),那将是最好的。 有没有办法做到这一点,或者我应该去寻求解决办法? 感谢

  • 更多的情况时,一个需要同 在快速路径,我可以创造(lazyly)一个std :: thread对象,发布一些任务给它(很多任务potentiall),和继续(在快速路径)没有被推迟!我可能不在乎孩子的线程真的在物理上被创建并恢复。 如果不能lazly已经在这样的快速pathes或期间的DllMain等
+0

您是否在DllMain中创建线程? – 2013-04-05 16:02:49

+0

其实我是在一个DLL范围的全局C++对象ctor中创建线程。我相信CRT做这些类型的工作人员的初始化从DllMain调用 – mami 2013-04-05 16:04:35

+0

他们被称为“DllMain”甚至进入之前我会说。老实说,我建议你延迟创建线程直到'DllMain'返回后。从你的dll导出'initialize()'函数,并要求加载模块来调用它(在加载dll后)。 'initialize()'函数将创建启动线程的对象。 – 2013-04-05 16:05:54

回答

3

的问题是不是在正在创建的线程方式,而是事实本身产生的物理线程这将是贝蒂您正在加载DLL时创建一个线程。虽然对CreateThread的调用可能是安全的(只要未启动的线程执行等待操作),it is in general a bad idea to create threads during DllMain

你应该在这里做的是导出一个初始化函数,并且需要加载模块在加载DLL后调用它。初始化函数然后会实例化所有必需的对象并创建所有必需的线程。

另请参阅this Q&A on StackOverflow

+0

那么我可以假设有没有做什么,我需要的方式:如果一个非空的std ::线程被创建的,它必然阻塞调用者,直到真的创建了物理线程和恢复?皮蒂... – mami 2013-04-05 16:26:02

+0

@mami:是的,没有办法,因为C++ 11标准规定了'性病的建设完成:: thread'必须与线程函数的开始同步(第30.3.1.2/5)。 – 2013-04-05 16:27:44

+0

好的,我明白了......很高兴! – mami 2013-04-05 16:32:00