2013-04-05 203 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