在函数中使用静态互斥量时出现无法解释的死锁情况

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之后执行是导致未定义行为的原因。 (如果需要代码可移植性,则应避免这种情况。)