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

When should you use std::thread::joinable?

本文关键字:thread joinable std 什么时候      更新时间:2023-10-16

网站上声明了cpp首选项关于std::thread::joinable:

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

std::thread::join 文档中的内容如下:

错误条件

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

这种方法的唯一目的是检测这种情况吗? 我们目前厚颜无耻地只调用线程>join而没有可加入的包装器,这种方法有什么危险?

根据您引用的信息:

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

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

因此,在程序/函数/例程即将结束时,当您想要加入线程时(并且您确实需要在std::thread超出范围之前执行此操作(,您必须有条件地执行此操作。这就是你这样做的方式。

#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;
};
<</div> div class="answers">

当您有一个可能已经联接的std::thread对象,或者可能没有引用实际的 thread of execution(TOE - 即操作系统线程(时,您可以使用joinable,并且如果尚未加入,则想要加入它。

例如,如果你正在实现提议的joinable_thread类,那么析构函数会说if(thr.joinable()) thr.join();,以涵盖有人已经显式调用join的情况。