Waiting for a std::thread to finish

Kristian D'Amato picture Kristian D'Amato · Nov 13, 2013 · Viewed 12.7k times · Source

I am trying to clean up gracefully on program termination, so I'm calling join() on a std::thread to wait for it to finish. This simply seems to block the main thread forever, but I don't understand why, because the worker thread is an (almost) empty loop like this:

void GameLoop::Run()
{
    while (run)
    {
        //  Do stuff... 
    }   
    std::cout << "Ending thread...\n";
}

I'm setting run to false before joining, of course. Now, I'm suspecting it's got something to do with it being a member function and being called upon object destruction. I'm creating the thread like this: runThread.reset(new thread(&GameLoop::Run, this));, where runThread is unique_ptr<std::thread> and a member of GameLoop. The join() call comes in the destructor of the GameLoop object.

Maybe the loop thread cannot finish if its object is in the process of being destroyed? According to the debugger the loop thread lingers on in the dark depths of msvcr120d.dll. If so, how would you handle it?

Beware: new to std::thread here!

Update: This is my call to join in the destructor:

run = false;
if (runThread->joinable())
{
    runThread->join();
}

Update 2: If I remove the join() I get an exception raised by ~thread()!

Answer

John Dibling picture John Dibling · Nov 13, 2013

Of course, when you join a thread that doesn't cause the thread to terminate. It simply blocks until that thread dies of natural (or unnatural) causes.

In order to clean up a multithreaded application gracefully, you need to somehow tell the worker thread that it is time to die, and then wait for the death to happen. The "wait for death to happen" part is what join is for.