在函数

时间:2017-01-12 16:24:02

标签: multithreading c++11 singleton mutex

下面的代码是我正在处理的实际代码的极端简化。这只适合任何人重现我所面临的问题。

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

程序执行到最后。 或者,如果我通过使构造函数公开来解决单例设计问题,并通过MyClass实例调用RunMyThread():

int main()
{
   // MyClass::Instance()->RunMyThread();
   MyClass o;
   o.RunMyThread();
   return 0;
}

程序也会执行到最后。

现在,如果我在Linux上使用gcc在顶部编译原始代码,则没有问题。程序执行到最后。

我无法弄清楚此代码中的哪些行为与平台有关。任何的想法?

2 个答案:

答案 0 :(得分:1)

这很可能是由Windows运行时清理内容的顺序引起的。你可以通过向你的类添加一个显式调用来测试这个:

ShutDown()
{
   mythread_.join();
}

从析构函数中取出join调用。然后在你的主要功能:

int main()
{
   MyClass::Instance()->RunMyThread();
   MyClass::Instance()->ShutDown();
   return 0;
}

答案 1 :(得分:1)

考虑到之前的评论/答案,问题的一个简单答案是:在主函数返回后允许线程执行是导致未定义行为的原因。 (如果要求代码可移植性,则应避免这种情况。)