std :: thread.join()死锁 [英] std::thread.join() deadlock

查看:508
本文介绍了std :: thread.join()死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

修改 我输入了错误的构造函数集mExit = true

Edit I typed wrong the contstructor set mExit = true

修改2 我正在使用带有v110_xp工具集的msvc2012.

Edit 2 I'm using msvc2012 with v110_xp toolset.

修改3 如果我在main内部明确调用gTest.release(),该问题就会消失.

Edit 3 The issue disappear if I explicity call gTest.release() inside main

推荐答案

我刚遇到这个问题,所以我为其他人发布了真正的答案.

I have just had this issue, so I post the real answer for others.

至少在Visual Studio中,有一个退出锁",当线程输入退出代码时(即,在main()之后代表主线程,在f()之后代表std::thread(f)),该锁被锁定.

In visual studio at least, there is an "exit lock", that is locked when a thread enters the exit code (ie. after main() for the main thread, and after f() for std::thread(f)).

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

As your Test class is only destructed after main() completes, the "exit lock" is locked. Only then you set mExit = true; and the other thread is allowed to complete. This other thread then waits to obtain the "exit lock" which is already taken by the main thread, while the main thread waits in mThread.join(); resulting in the deadlock.

是的,您需要在主线程完成之前加入所有线程.

So yes, you need to join all your threads before the main thread has completed.

这篇关于std :: thread.join()死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆