我不明白为什么这个简单的片段有死锁:
#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;
}
修改 我输错了contstructor set mExit = true
编辑2 我正在使用msvc2012和v110_xp工具集。
编辑3 如果我明确地在main
中调用gTest.release(),问题就会消失答案 0 :(得分:7)
我刚刚遇到这个问题,所以我发布了其他人的真实答案。
至少在visual studio中,有一个“退出锁定”,当线程进入退出代码时(即在主线程的main()
之后,以及f()
之后{ {1}})。
由于您的Test类仅在std::thread(f)
完成后被破坏,因此“退出锁定”被锁定。只有这样你才能设置main()
,并允许其他线程完成。这个其他线程然后等待获取主线程已经采用的“退出锁定”,而主线程在mExit = true;
中等待导致死锁。
所以是的,你需要在主线程完成之前加入所有线程。
答案 1 :(得分:3)
对我来说,代码看起来没问题,如果它与本地dut坏了全局我怀疑类与deinit序列相关。连接在退出时发生,并且实现可能已经消除了一些结构。不应该是这种情况,但可能。
在任何情况下,我总是避免在main之前启动线程,并留下main的任何到达端。我认为那只是在惹麻烦。如果你可以重新安排它以在较小的点上强制加入,整个问题可能会消失。
你也应该使用atomic_flag而不是原子。
答案 2 :(得分:0)
从
更改代码gTest = TestPtr(新测试);
到
auto gTest = std :: make_unique();
消除问题。
上面提到全局对象的问题。