2014-09-06 54 views
10

我有一個多線程的應用程序,有一個循環等待用戶輸入作爲主線程。 在正確的輸入上,它應該停止循環並等待所有其他線程,以便正常結束。std ::列表<std::future>析構函數不會阻止

爲此,我創建了一個的std ::名單中,我把的std ::線程創建

std::list<std::future<int>> threads; 
threads.emplace_front(std::async(std::launch::async, ...)); 

我的印象是創造未來對象,讓列表因爲列表的析構函數將破壞所有的 std :: future元素和the destructor of those將等待線程完成。

編輯:既然是相關的,我將其添加在這裏: 這是Win7上與MSVC版本的Visual Studio 2013專業版 /EDIT

當我嘗試這樣做,它沒有塊,我不得不添加

for (auto it = threads.begin(); it != threads.end(); ++it) { 
    it->get(); 
} 

要結束的功能,要正確地阻止。

我誤解了一些東西,還是必須以不同的方式創建線程,才能做我想在這裏做的事情?

+0

@ T.C.如果真的那麼簡單,我不應該依賴它們來阻止,你應該添加這個作爲答案,所以我可以接受它 – Ongy 2014-09-06 09:14:09

+4

看起來像一個bug。什麼是編譯器? – ixSci 2014-09-06 09:14:57

+0

嗯,斯科特·邁耶斯[提出一個很好的論點](http://scottmeyers.blogspot.com/2013/03/stdfutures-from-stdasync-arent-special.html)「std :: async'的規範要求它阻止。有趣的... – 2014-09-06 09:16:33

回答

12

這是一個MSVC bug that has been fixed,但直到MS發佈了Visual C++的新版本,在2015年可能是一些時間(這也是available in the CTP for the new version,但它的使用,對於任何生產一個非常糟糕的主意修復將不可用代碼...)

如斯科特邁爾斯在his blog post解釋的那樣,通過使用launch::async策略std::async調用返回一個std::future的析構函數需要阻塞,直到產生的線程完成執行(§30.6.8[期貨。異步]/P5):

如果實現選擇了launch::async政策,

  • [...]
  • 相關線程完成(1.10)的 從返回同步第一個函數,它成功檢測到共享狀態的準備就緒狀態,或者從最後一個函數 返回的狀態釋放共享狀態,以先發生者爲準。

在這種情況下,future的析構函數是‘釋放的共享狀態最後一個函數’,所以線程完成必須同步與(即之前發生)是函數的返回。

+0

+1 MS與VS2010正則表達式錯誤地做了類似的事情,涉及錯誤地被+1的序列​​計數。其結果是使用他們的正則表達式,你必須「破壞」你的表達,以便它們「實現」它們的實現,但實際上是*錯誤*表達式,因此在其他任何地方都無法工作。正如你所想象的那樣,雖然很久以前他們知道這個問題,但是MS決定不在SP1中解決這個問題,但沒有得到很好的迴應(人們非常憤怒)。至少在這裏,我們可以將你的未來包裝在一個可移動的應用程序中,它可以在銷燬時調用'.wait()',所以你有一個可行的選擇。 – WhozCraig 2014-09-06 09:46:48

+0

感謝您的鏈接!剛剛因爲這個bug而崩潰了。 – Mikhail 2015-11-25 16:28:30

0

我看過的std ::未來的文檔,發現這個對的std ::未來的析構函數:

發佈任何共享的狀態。這意味着

  • 如果返回的對象或提供商保留最後的參考到它的共享狀態,該共享狀態被破壞;和
  • 返回對象或提供者放棄對其共享狀態的引用;和
  • 這些操作不會阻止共享狀態準備就緒,除非它可能會阻止如果以下所有條件都成立:共享狀態是通過調用std :: async創建的,共享狀態是尚未準備就緒,這是共享狀態的最後一個參考。

注意最後一點。在我看來,你必須在範圍的最後打電話給get

+0

'future's dtor'應該阻止如果未來是通過'async'調用獲得的。不需要'get' – ixSci 2014-09-06 09:23:20

+0

@ixSci如果你沒有使用std :: async,情況也是這樣嗎? – Franz 2014-09-06 09:26:05

+0

不,這對'std :: async'調用很特殊。雖然這很令人困惑。看看@ T.C的鏈接。張貼在原始問題的評論。 – ixSci 2014-09-06 09:28:35

相關問題