2016-10-04 115 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

回答