简体   繁体   English

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

[英]When should you use std::thread::joinable?

It is stated on the site cppreference with respect to std::thread::joinable : 关于std :: thread :: joinable的网站cppreference中陈述了:

Checks if the thread object identifies an active thread of execution. 检查线程对象是否标识了活动的执行线程。 Specifically, returns true if get_id() != std::thread::id(). 具体来说,如果get_id()!= std :: thread :: id(),则返回true。 So a default constructed thread is not joinable. 因此默认构造的线程不可连接。 A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable. 已完成执行代码但尚未加入的线程仍被视为活动执行线程,因此可以连接。

What follows on the std::thread::join documentation: 关于std :: thread :: join文档的内容如下:

Error Conditions 错误条件

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

Is the only purpose of this method to detect such a situation? 这种方法的唯一目的是检测这种情况吗? We currently and brazenly only call thread->join without a joinable wrapper, what is the danger of such an approach? 我们目前肆无忌惮地只调用thread-> join而没有可连接的包装器,这种方法有什么危险?

You use joinable when you have a std::thread object which may already have been joined, or may not reference an actual t hread o f e xecution (TOE - ie, OS thread), and you want to join it if not already joined. 您可以使用joinable ,当你有一个std::thread可能已经被加入了对象,也可以不引用实际的牛逼 hread 华氏度 éxecution(TOE -即OS线程),并且你想加入它,如果不是已经加入。

eg if you were implementing the proposed joinable_thread class, then the destructor would say if(thr.joinable()) thr.join(); 例如,如果你正在实现建议的joinable_thread类,那么析构函数会说if(thr.joinable()) thr.join(); , to cover the case that someone already called join explicitly. ,以涵盖有人已经明确join的情况。

From the information you quoted: 根据您引用的信息:

So a default constructed thread is not joinable. 因此默认构造的线程不可连接。

There's your answer. 有你的答案。 If you don't know whether your thread was default constructed or not, you do not know whether it was joinable. 如果你不知道你的线程是否是默认构造的,你不知道它是否可以连接。

So, near the end of your program/function/routine, when you want to join the thread (and you do need to do this, before the std::thread goes out of scope), you must do it conditionally . 因此,在程序/函数/例程的末尾,当您想要加入线程时(并且您需要在std::thread超出范围之前执行此操作),您必须有条件地执行此操作。 And this is how you do that. 这就是你如何做到的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM