如何在 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_exitset_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++ 中注册线程退出处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在应用程序退出()期间处理 Qthread 终止?

在 C# 应用程序退出时清理非托管 C++ 线程

如何获取程序返回值,退出码,错误码

如何安全地终止线程? (使用指针)C++

C++怎么在主线程中使用子线程的数据? 比如说主线程中有一个数组,如何在子线程中调用这个数组

linux c开发: 在程序退出时进行处理