std::thread.join() deadlock

std::thread.join() deadlock

本文关键字:deadlock join thread std      更新时间:2023-10-16

我不明白为什么这个简单的代码片段有一个死锁:

#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;
}

编辑我输入了错误的构造函数设置mExit = true

Edit 2 我正在使用msvc2012与v110_xp工具集。

编辑3 如果我在main

中显式调用gTest.release(),问题就会消失。

我刚刚遇到了这个问题,所以我把真实的答案贴出来给别人。

至少在visual studio中,有一个"退出锁",当线程进入退出代码时,它被锁定。main()后为主线程,f()后为std::thread(f))。

由于您的Test类仅在main()完成后才被销毁,因此"退出锁"被锁定。只有设置了mExit = true;,另一个线程才被允许完成。另一个线程等待获得主线程已经获得的"退出锁",而主线程在mThread.join();中等待导致死锁。

所以,是的,你需要在主线程完成之前连接所有的线程。

对我来说,代码看起来不错,如果它可以与局部dut和全局我怀疑类相关的deinit序列。连接发生在出口深处,实现可能已经消除了一些结构。这不应该是这样,但却是可能的。

在任何情况下,我总是避免在main之前启动线程,并留下任何到达main的结束。我认为那是自找麻烦。如果你能重新安排它,在稍早一点的时候强制连接,整个问题可能会消失。

还应该在atomic上使用atomic_flag

修改代码

gTest = TestPtr(new Test);

auto gTest = std::make_unique();

解决问题。