当我创建一个新线程时,我想等到新线程到达特定点。直到现在,我已经通过在创建函数等待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