你什么时候应该使用std :: thread :: joinable?

时间:2017-03-21 10:31:21

标签: c++ multithreading c++11

关于std::thread::joinable

的网站cppreference中说明了这一点
  

检查线程对象是否标识了活动的执行线程。   具体来说,如果get_id()!= std :: thread :: id(),则返回true。那么一个   默认构造的线程不可连接。一个完成的线程   执行代码,但尚未加入仍被认为是   活动的执行线程,因此可以连接。

std::thread::join文档后面的内容:

  

错误条件

     

resource_deadlock_would_occur如果this-> get_id()==   std :: this_thread :: get_id()(检测到死锁)

此方法的唯一目的是检测这种情况吗?我们目前肆无忌惮地只调用thread-> join而没有可连接的包装器,这种方法有什么危险?

2 个答案:

答案 0 :(得分:5)

如果您的joinable对象可能已加入,或者可能未引用实际的 t hread o ,则使用std::thread f e xecution(TOE - 即OS线程),如果尚未加入,则要加入。

e.g。如果您正在实施建议的joinable_thread类,则析构函数会说if(thr.joinable()) thr.join();,以涵盖某人已明确调用join的情况。

答案 1 :(得分:3)

根据您引用的信息:

  

因此默认构造的线程不可连接。

有你的答案。如果你不知道你的线程是否是默认构造的,你不知道它是否可以连接。

所以,在你的程序/函数/例程的末尾,当你想要加入线程时(你需要在std::thread超出范围之前执行此操作),你必须这样做< EM>有条件。这就是你如何做到的。

#include <thread>

void bar(const unsigned int);

/**
 * This class may be default-constructed (in which case it does nothing),
 * or constructed with an `unsigned int` argument which shall be passed
 * to `bar()` in a worker thread.
 */
struct Foo
{
   Foo() {}

   Foo(const unsigned int x)
      : doThingsThread([&]() { bar(x); })
   {}

   ~Foo()
   {
      // The thread *MUST* be joined before destruction, if it
      // is joinable. Otherwise, it *CAN'T* be joined.
      if (doThingsThread.joinable())
         doThingsThread.join();
   }
private:
   std::thread doThingsThread;
};