2013-08-23 40 views
-1

我想確保線程在對象被銷燬之前完成。std :: C++中的線程11,如何確保線程在析構函數中完成

這裏是最基本的例子我能想到的:

struct User { 
    std::thread worker_thread; 

    ~User() { 
     if (worker_thread.joinable()) { 
      worker_thread.join(); 
     } 
    } 
}; 

這是一個正確的解決問題的方法?

+2

我看到它確定,但你必須確保線程最終會完成。如果它是一個無限循環的服務器線程,則應首先發出信號。 – rodrigo

+0

您需要正確退出線程... – lpapp

+0

'std :: thread'是一個低級別的原語。像上面這樣的事情是避免未定義行爲的一種體面的最後方式,但是如果你想使用原始的'std :: thread',你不應該:你應該把它們包裝在更多的層中而不是薄的東西。 – Yakk

回答

2

這是不正確的,因爲join()可能會拋出異常,並且您不想讓任何異常轉義任何析構函數。從草藥Sutters Exceptional C++在部分破壞者投擲和爲什麼他們是邪惡的。

遵守規範的異常安全規則:決不讓一個例外,從析構函數或重載運算符delete()operator delete[]();寫每一個析構和釋放功能,雖然它有「throw() 異常規範逃脫。 「

+2

嗯,這就是爲什麼代碼檢查線程是否可以連接。當然,也有可能代碼試圖加入當前線程,但這是嚴重設計錯誤的結果,並且不應產生異常偏執狂。但是如果你真的**擔心會出現異常,請將該呼叫包裝在try塊中。 –

+0

是的,我同意皮特在這裏。 – lpapp

+0

從[C++參考](http://en.cppreference.com/w/cpp/thread/thread/join)'std :: thread :: join()'被允許拋出'std :: system_error' if 'joinable()== false'或發生_error_。 例外的主要好處之一是,它們有助於消除編程錯誤。所以在析構函數中調用'join()'絕對需要一個try-catch塊(感謝Pete Becker指出了這一點),但是特定的catch塊則負責報告與你的平臺相關的任何莊園的編程錯誤。 –

1

我也認爲它在評論中提到的很好,但是您需要確保在需要時正確退出線程。例如,如果您有一個循環計數器緩慢倒計時,您需要在長等待隊列之前正確關閉。更重要的是,當你有一個「無盡的」布爾條件,例如必須被切換時,等等。

+1

worker_thread可能正在編寫一個文件,所以我想確保文件在線程破壞之前完成。 – Grapes

+0

是的,那很好,我會說,雖然你可能想用那個更新你的問題。 ;-) – lpapp