【问题标题】:When should you use std::thread::joinable?什么时候应该使用 std::thread::joinable?
【发布时间】:2017-08-12 23:09:33
【问题描述】:

关于std::thread::joinable的网站cppreference上有说明:

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

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

错误情况

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

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

【问题讨论】:

标签: c++ multithreading c++11


【解决方案1】:

根据您引用的信息:

所以默认构造的线程是不可连接的。

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

所以,在你的程序/函数/例程快结束时,当你想加入线程时(你确实需要这样做,在 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;
};

【讨论】:

  • +1 在这里获取更多信息和示例——正是我想要的。徘徊是否可以提供进一步的说明:根据我阅读的内容(在其他问题和 std::thread 文档中),如果线程在可连接时未连接,那么当线程 doThingsThread 的析构函数被调用时:If *this has an associated thread (joinable() == true), std::terminate() is called. 这意味着您的整个应用程序将终止,因为 std::terminate() 被称为 :o ...这就是我所理解的...
  • @code_fodder:不,因为我做了doThingsThread.join(),然后joinable() == false,因此线程的析构函数是安全的。确实,这就是 为什么我使用join。您可以将joinable() 视为needs_to_be_joined_please()
  • 是的,这就是我要澄清的内容:)“如果线程是 not 在可加入时加入,那么......事情会出错”。我并不是说你没有重新加入主题,我正在澄清“为什么” - 即如果你不这样做,那么事情可能会出错:o ...但无论如何,现在很清楚,谢谢:)
【解决方案2】:

当您有一个可能已经加入的std::thread 对象时,您使用joinable,或者可能没有引用实际的t线程of e执行(TOE - 即操作系统线程),如果尚未加入,您想加入它。

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

【讨论】:

  • 你的意思是if(thr.joinable()) thr.join(); 吗?
  • 我发现这个简短的讲座(由 Scott Meyers 撰写)非常有用(最后约 15 分钟讨论了关于 std::thread 的“加入”问题):channel9.msdn.com/Events/GoingNative/2013/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多