什么会导致可连接线程在调用join时失败

What can cause a joinable thread to fail when calling join

本文关键字:调用 join 失败 线程 可连接 什么      更新时间:2023-10-16

当我调用joinThread时,我偶尔会得到一个带有"无效参数"的std::system_error抛出;在加入呼叫中。这个错误似乎只有在我用gcc编译时才会出现,而且它不能始终如一地重现,也就是说,它偶尔会发生,而且不可预测。有人知道是什么导致了这样的错误吗?

下面是我的代码的简化版本。

class exampleClass
{
   public:
   exampleClass()
   {
   }
   
   ~exampleClass()
   {
      joinThread();
   }
   void doWork()
   {
       joinThread();
       workThread = std::thread(&exampleClass::threadFunction, this);
   }
   void joinThread()
   {
      if(workThread.joinable()) workThread.join();
   }
   protected:
   void threadFunction()
   {
      std::cout << "Do something that requires time..." << std::endl
   }
   std::thread       workThread;
}

因为你没有提供一个例子,这个错误发生的地方,我只能从我自己的经验讲。为了避免这样的错误,您应该考虑以下几点:

  • 你的线程是默认构造的吗?您是否使用有效的回调函数初始化它?
  • 你的线程被分离了吗?
  • 你的线程被move了吗?
  • 线程是否试图访问已保留的资源?想想可能的死锁来源!也许你被困在某个地方了。(但是线程应该仍然是可连接的。)
  • friend方法或类是否尝试访问/使用/加入线程?

我最近忘记把一个函数传递给一个线程,这个线程是我为了以后使用而默认构造的。这是由于条件初始化过程造成的。所以关于你的例子类上面:您的workThread是在构造exampleClass的对象时默认构造的。只有在调用doWork()时,才会传递回调函数。您已经确保线程只有在处于可连接状态时才被连接。在对象被销毁时,这也是有保证的。因此,我能想到的最可能的原因,为什么这可能会失败,如果你有一个friend。你没有把它放在你的例子中,但也许你忽略了这一点,因为你想要呈现一个简化的形式。

也许也看看这里:http://cppatomic.blogspot.com/2018/05/modern-effective-c-make-stdthread.html可能会有所帮助。