Std :: thread.join () deadlock

I don't understand why this simple snippet has a dead lock:

#include <atomic> #include <thread> #include <memory> using namespace std; class Test { public: Test() : mExit( false ) { mThread = thread( bind( &Test::func, this ) ); } ~Test() { if ( mThread.joinable() ) { mExit = true; mThread.join(); } } private: void func() { while ( !mExit ) { // do something } } private: atomic< bool > mExit; thread mThread; }; typedef unique_ptr< Test > TestPtr; TestPtr gTest; int main() { gTest = TestPtr( new Test ); return 0; } 

Edit I typed the wrong set of counterstructors mExit = true

Edit 2 I am using msvc2012 with the v110_xp toolkit.

Edit 3 The problem disappears if I explain the call to gTest.release () inside the main

+8
c ++ multithreading
source share
3 answers

I just had this problem, so I am posting a real answer to others.

In the visual studio, at least there is an β€œexit lock” that blocks when the thread enters the exit code (that is, after main() for the main thread and after f() for std::thread(f) ).

Since your test class is destroyed only after main() , blocking the output is blocked. Only after that will you set mExit = true; and another thread will be completed. Then this other thread waits for an β€œexit lock” that is already taken by the main thread, while the main thread waits in mThread.join(); leading to a deadlock.

So yes, you need to attach all your threads before the main thread completes.

+6
source share

For me, the code looks fine, if it's fine with the local dut bad with global, I suspect the class is associated with a deinite sequence. Joining takes place deep in the outlet, and the implementation may have already eliminated some structures. It should not be, but it is possible.

In any case, I always avoid running the thread in front of main and leave either end of the end. I believe that only asking for trouble. If you can rearrange it to force a connection at an earlier point, the whole problem may evaporate.

Also you should probably use atom_flag over the atom.

+3
source share

Change code from

gTest = TestPtr (new test);

to

auto gTest = std :: make_unique ();

to solve a problem.

the problem is like the point above with a global object.

0
source share

All Articles