Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger code when a thread exits, without using functions *_at_thread_exit?

Let's say I have two threads in my application, and I need my main thread to be notified when the other one exits.

I am aware that C++11 provides std::notify_all_at_thread_exit(), or std::promise::set_{value,exception}_at_thread_exit(), and that's exactly what I am looking for, however the version of the STL I use (4.7.2) does not implement these functions yet (see points 30.5 and 30.6.5 on this page).

Is there any chance I can mimic that? Thanks,

like image 573
piwi Avatar asked Sep 24 '26 22:09

piwi


1 Answers

If you don't mind using Boost, there is boost::notify_all_at_thread_exit() in Boost.Thread.

This could also be done using a thread-local variable, which registers a callback at the destructor. This is actually how the function is implemented in libc++. Unfortunately gcc 4.7 doesn't support the thread_local storage class yet, so this cannot work.

But if we are allowed to use POSIX thread functions, then we could associate a destructor to a TLS with pthread_key_create, which allowed us to simulate the function as:

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)));
}

(This is optimized for one variable only. You may change this to register a stack of condition variables.)

like image 92
kennytm Avatar answered Sep 26 '26 10:09

kennytm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!