检查线程对象是否标识了活动的执行线程。 具体来说,如果get_id()!= std :: thread :: id(),则返回true。那么一个 默认构造的线程不可连接。一个完成的线程 执行代码,但尚未加入仍被认为是 活动的执行线程,因此可以连接。
std::thread::join文档后面的内容:
错误条件
resource_deadlock_would_occur如果this-> get_id()== std :: this_thread :: get_id()(检测到死锁)
此方法的唯一目的是检测这种情况吗?我们目前肆无忌惮地只调用thread-> join而没有可连接的包装器,这种方法有什么危险?
答案 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;
};