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 join
ing, 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()
!
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.