我想確保線程在對象被銷燬之前完成。std :: C++中的線程11,如何確保線程在析構函數中完成
這裏是最基本的例子我能想到的:
struct User {
std::thread worker_thread;
~User() {
if (worker_thread.joinable()) {
worker_thread.join();
}
}
};
這是一個正確的解決問題的方法?
我想確保線程在對象被銷燬之前完成。std :: C++中的線程11,如何確保線程在析構函數中完成
這裏是最基本的例子我能想到的:
struct User {
std::thread worker_thread;
~User() {
if (worker_thread.joinable()) {
worker_thread.join();
}
}
};
這是一個正確的解決問題的方法?
這是不正確的,因爲join()
可能會拋出異常,並且您不想讓任何異常轉義任何析構函數。從草藥Sutters Exceptional C++在部分破壞者投擲和爲什麼他們是邪惡的。:
遵守規範的異常安全規則:決不讓一個例外,從析構函數或重載運算符
delete()
或operator delete[]();
寫每一個析構和釋放功能,雖然它有「throw()
異常規範逃脫。 「
嗯,這就是爲什麼代碼檢查線程是否可以連接。當然,也有可能代碼試圖加入當前線程,但這是嚴重設計錯誤的結果,並且不應產生異常偏執狂。但是如果你真的**擔心會出現異常,請將該呼叫包裝在try塊中。 –
是的,我同意皮特在這裏。 – lpapp
從[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塊則負責報告與你的平臺相關的任何莊園的編程錯誤。 –
我看到它確定,但你必須確保線程最終會完成。如果它是一個無限循環的服務器線程,則應首先發出信號。 – rodrigo
您需要正確退出線程... – lpapp
'std :: thread'是一個低級別的原語。像上面這樣的事情是避免未定義行爲的一種體面的最後方式,但是如果你想使用原始的'std :: thread',你不應該:你應該把它們包裝在更多的層中而不是薄的東西。 – Yakk