如何在线程退出时触发代码,而不使用函数* _at_thread_exit?

时间:2013-10-04 08:21:53

标签: c++ multithreading c++11

假设我的应用程序中有两个线程,当另一个线程退出时,我需要通知主线程。

我知道C ++ 11提供std::notify_all_at_thread_exit()std::promise::set_{value,exception}_at_thread_exit(),这正是我正在寻找的,但是我使用的STL版本(4.7.2)没有实现这些功能(参见this page上的第30.5和30.6.5点)。

我有可能模仿那个吗?谢谢,

1 个答案:

答案 0 :(得分:1)

如果你不介意使用Boost,Boost.Thread中有boost::notify_all_at_thread_exit()

这也可以使用线程局部变量来完成,它在析构函数中注册一个回调。这实际上是如何在libc ++中实现该函数。不幸的是,gcc 4.7还不支持thread_local存储类,所以这不起作用。

但是如果允许我们使用POSIX线程函数,那么我们可以将析构函数与pthread_key_create的TLS相关联,这允许我们将函数模拟为:

void notify_all_at_thread_exit(std::condition_variable& cv,
                               std::unique_lock<std::mutex> lock) {
    using Arg = std::tuple<pthread_key_t, 
                           std::condition_variable*, 
                           std::unique_lock<std::mutex>>;

    pthread_key_t key;
    pthread_key_create(&key, [](void* value) {
        std::unique_ptr<Arg> arg (static_cast<Arg*>(value));
        std::get<2>(*arg).unlock();
        std::get<1>(*arg)->notify_all();
        pthread_key_delete(std::get<0>(*arg));
    });

    pthread_setspecific(key, new Arg(key, &cv, std::move(lock)));
}

(这仅针对一个变量进行了优化。您可以将其更改为注册一组条件变量。)