2016-10-04 126 views
-2

當我創建一個新線程時,我想等到新線程到達特定點。直到現在,我已經通過在創建函數等待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設置一個默認的異常。但無論如何,使用這個承諾/未來的設計在我看來似乎是一個骯髒的解決方法。那麼,什麼是實現異常安全等待的最好和最優雅的方式?

+0

可能將'std :: function'傳遞給你的線程函數? –

+0

['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

+0

此外,你可以使用['std :: condition_variable'](http://en.cppreference.com/w/cpp/thread/condition_variable)和一個在線程退出時釋放的RAII包裝器(或者一旦你的線程手動釋放是「開始」) – lcs

回答