如何在 C++ 中注册线程退出处理程序?
Posted
技术标签:
【中文标题】如何在 C++ 中注册线程退出处理程序?【英文标题】:How to register a thread-exit-handler in C++? 【发布时间】:2016-10-04 17:27:53 【问题描述】:当我创建一个新线程时,我想等到新线程到达特定点。到目前为止,我已经通过在创建函数等待future.get()
时传递给线程的承诺解决了这个问题。如果新线程的初始化失败,我给promise设置一个异常,这样future.get()
也会抛出异常。
这看起来像这样:
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
让我感到不安的是,线程可能在其初始化阶段失败,并出现我无法处理的错误。然后,我不会为 promise 设置适当的异常,主函数将无限等待future.get()
返回。考虑到这一点,在我看来,我的解决方案很容易出错且设计糟糕。
我了解了 RAII 以及它如何为您提供异常安全性,因为您可以在析构函数中进行清理。我想将类似的模式应用于上述情况。因此,我想知道是否有诸如线程析构函数或退出处理程序之类的东西,我可以在其中为 promise 设置默认异常。但无论如何,在我看来,使用这种承诺/未来设计似乎是一种肮脏的解决方法。那么,实现异常安全等待的最佳和最优雅的方式是什么?
【问题讨论】:
可能将std::function
传递给您的线程函数?
set_value_at_thread_exit
和 set_exception_at_thread_exit
。
此外,您可以使用带有 RAII 包装器的 std::condition_variable
,该包装器在线程退出时释放(或在线程“启动”后手动释放)
我猜如果我使用 set_exception_at_thread_exit,promise 的共享状态将被设置,所以我不能再使用 set_value。并且编写一个 RAII-wrapper 意味着:没有现成的线程安全解决方案,我必须自己实现它?
【参考方案1】:
最后,我偶然找到了一个答案:我想这可以用std::condition_variable
来完成,而如果新创建的线程过早终止,则可以用std::notify_all_at_thread_exit
通知正在等待的线程。
【讨论】:
提防cplusplus.github.io/LWG/issue3343以上是关于如何在 C++ 中注册线程退出处理程序?的主要内容,如果未能解决你的问题,请参考以下文章