當我創建一個新線程時,我想等到新線程到達特定點。直到現在,我已經通過在創建函數等待future.get()
時傳遞給線程的承諾來解決此問題。如果新線程的初始化失敗,我將對該承諾設置一個例外,以便future.get()
也會拋出異常。如何在C++中註冊線程退出處理程序?
這看起來是這樣的:
boost::promise<bool> promiseThreadStart;
void threadEntry();
int main(int argc, char* argv[])
{
// Prepare promise/future
promiseThreadStart = boost::promise<bool>();
boost::unique_future<bool> futureThreadStarted = promiseThreadStart.get_future();
// Start thread
boost::thread threadInstance = boost::thread(threadEntry);
// Wait for the thread to successfully initialize or to fail
try {
bool threadStarted = futureThreadStarted.get();
// Started successfully
}
catch (std::exception &e) {
// Starting the thread failed
}
return 0;
}
void threadEntry() {
// Do some preparations that could possibly fail
if (initializationFailed) {
promiseThreadStart.set_exception(std::runtime_error("Could not start thread."));
return;
}
// Thread initialized successfully
promiseThreadStart.set_value(true);
// Do the actual work of the thread
}
什麼這裏打亂了我的是一個事實,即線程可以在與我不處理錯誤的初始化階段失敗。然後,我不會爲承諾設置適當的例外,主函數將無限等待future.get()
返回。考慮到這一點,我的解決方案似乎很容易出錯,設計也很糟糕。
我已經瞭解了RAII以及它如何爲異常安全提供給您,因爲您可以在析構函數中進行清理。我想對上述情況採用類似的模式。因此,我想知道是否有像線程析構函數或退出處理程序那樣的地方,我可以爲promise設置一個默認的異常。但無論如何,使用這個承諾/未來的設計在我看來似乎是一個骯髒的解決方法。那麼,什麼是實現異常安全等待的最好和最優雅的方式?
可能將'std :: function'傳遞給你的線程函數? –
['set_value_at_thread_exit'](http://en.cppreference.com/w/cpp/thread/promise/set_value_at_thread_exit)和['set_exception_at_thread_exit'](http://en.cppreference.com/w/cpp/thread/承諾/ set_exception_at_thread_exit)。 – lcs
此外,你可以使用['std :: condition_variable'](http://en.cppreference.com/w/cpp/thread/condition_variable)和一個在線程退出時釋放的RAII包裝器(或者一旦你的線程手動釋放是「開始」) – lcs