在函数中使用静态互斥量时出现无法解释的死锁情况
Unexplained dead lock situation when using static mutex in function
下面的代码是我正在处理的实际代码的极端简化。这只是为了让任何人都能重现我面临的问题。
#include <mutex>
#include <thread>
using std::mutex;
using std::thread;
void Do()
{
static mutex myMutex;
static int dataToProtect;
return;
}
class MyClass
{
public:
~MyClass()
{
mythread_.join();
}
void RunMyThread()
{
mythread_ = thread(&Do);
}
static MyClass *Instance()
{
static MyClass single;
return &single;
}
private:
MyClass()
{}
std::thread mythread_;
};
int main()
{
MyClass::Instance()->RunMyThread();
return 0;
}
在 MinGW-w64 上执行 gcc 时,执行卡在:
static mutex myMutex;
看起来是线程和单例设计的结合造成了这个问题,因为如果我在不使用线程的情况下调用 Do():
void RunMyThread()
{
// mythread_ = thread(&Do);
Do();
}
程序执行到最后。
或者,如果我通过创建构造函数 public 来绕过单例设计,并且我通过 MyClass:
的实例调用 RunMyThread()
int main()
{
// MyClass::Instance()->RunMyThread();
MyClass o;
o.RunMyThread();
return 0;
}
程序也执行到最后
现在,如果我在 Linux 上用 gcc 编译顶部的原始代码,就没有问题。程序执行到最后。
我无法弄清楚这段代码中的哪些行为是平台相关的。任何的想法?
这很可能是由 Windows 运行时清理内容的顺序造成的。您可以通过向您的 class 添加显式调用来对此进行测试,如下所示:
ShutDown()
{
mythread_.join();
}
从析构函数中取出连接调用。然后在你的主要功能中:
int main()
{
MyClass::Instance()->RunMyThread();
MyClass::Instance()->ShutDown();
return 0;
}
考虑到前面的comments/answers,问题的一个简单答案是:允许线程在主函数returns之后执行是导致未定义行为的原因。
(如果需要代码可移植性,则应避免这种情况。)
下面的代码是我正在处理的实际代码的极端简化。这只是为了让任何人都能重现我面临的问题。
#include <mutex>
#include <thread>
using std::mutex;
using std::thread;
void Do()
{
static mutex myMutex;
static int dataToProtect;
return;
}
class MyClass
{
public:
~MyClass()
{
mythread_.join();
}
void RunMyThread()
{
mythread_ = thread(&Do);
}
static MyClass *Instance()
{
static MyClass single;
return &single;
}
private:
MyClass()
{}
std::thread mythread_;
};
int main()
{
MyClass::Instance()->RunMyThread();
return 0;
}
在 MinGW-w64 上执行 gcc 时,执行卡在:
static mutex myMutex;
看起来是线程和单例设计的结合造成了这个问题,因为如果我在不使用线程的情况下调用 Do():
void RunMyThread()
{
// mythread_ = thread(&Do);
Do();
}
程序执行到最后。 或者,如果我通过创建构造函数 public 来绕过单例设计,并且我通过 MyClass:
的实例调用 RunMyThread()int main()
{
// MyClass::Instance()->RunMyThread();
MyClass o;
o.RunMyThread();
return 0;
}
程序也执行到最后
现在,如果我在 Linux 上用 gcc 编译顶部的原始代码,就没有问题。程序执行到最后。
我无法弄清楚这段代码中的哪些行为是平台相关的。任何的想法?
这很可能是由 Windows 运行时清理内容的顺序造成的。您可以通过向您的 class 添加显式调用来对此进行测试,如下所示:
ShutDown()
{
mythread_.join();
}
从析构函数中取出连接调用。然后在你的主要功能中:
int main()
{
MyClass::Instance()->RunMyThread();
MyClass::Instance()->ShutDown();
return 0;
}
考虑到前面的comments/answers,问题的一个简单答案是:允许线程在主函数returns之后执行是导致未定义行为的原因。 (如果需要代码可移植性,则应避免这种情况。)