Search code examples
c++c++11stdthread

Test if join has been called


Is it legal to call the joinable() function inside a thread's while loop to test if there was a join request on the thread or are there any side effects I do not consider at the moment?


Solution

  • Is it legal to call the joinable() function inside a thread's while loop to test if there was a join request on the thread or are there any side effects I do not consider at the moment?

    This will probably cause a data race (therefore undefined behaviour) unless you use some kind of manual synchronization.

    std::thread::join() is a non-const member function, therefore any call to it that is potentially concurrent with any other call to a member function of the same object will conflict, and cause a data race.

    So if one thread calls std::thread::join() and another thread concurrently calls std::thread::joinable() on the same object, you have a data race, and undefined behaviour.

    You can fix this by using a mutex to serialize the calls so that only one object is accessing the thread at any one time, but instead I would consider if your design makes sense. Hint: it doesn't. Calling joinable() will tell you if the thread has been joined, not if a call to join() has started. A thread can't be joined while it's still running (the call to join() will block and wait for it to finish). So the running thread can never see joinable() == false for the std::thread object that manages it, because if it's able to call joinable() then it's still running, and so it's joinable!

    So:

    1. Trying to do this risks undefined behaviour unless you're very careful.

    2. It doesn't makes sense anyway.

    Instead use something like a std::atomic<bool> (or a bool and a std::mutex) that records whether the thread has been requested to stop running, and check it from the running thread.