C 中多线程的 join() 和 detach() 有什么不同?

新手上路,请多包涵

在 C++ 的多线程中, join()detach() 有什么不同? join() 会杀死线程吗?

原文由 r.hg 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

C++ thread 对象通常(但不总是)表示执行线程,这是一个操作系统或平台概念。

当调用 thread::join() 时,调用线程将阻塞,直到执行线程完成。基本上,这是一种可以用来知道线程何时完成的机制。当 thread::join() 返回时,操作系统线程已经完成,C++ thread 对象可以被销毁。

当调用 thread::detach() 时,执行线程与 thread 对象“分离”,不再由 thread 对象表示 - 它们是两个独立的事物。 C++ thread 对象可以被销毁,操作系统线程可以继续执行。如果程序需要知道执行线程何时完成,则需要使用其他机制。 join() 不能再对该 thread 对象调用,因为它不再与执行线程相关联。

在 C++ thread 对象仍然“可连接”时销毁它被认为是错误的。也就是说,为了销毁 C++ thread 对象 join() 需要被调用(并完成)或 detach() 必须被调用。如果一个 C++ thread 对象在被销毁时仍然可以连接,则会抛出异常。

C++ thread 对象不代表执行线程的其他一些方式(即,可以是不可连接的):

  • 默认构造的 thread 对象不代表执行线程,因此不可连接。
  • 已从中移出的线程将不再代表执行线程,因此不可连接。

原文由 Michael Burr 发布,翻译遵循 CC BY-SA 4.0 许可协议

join() 不会杀死线程。实际上它一直等到线程主函数返回。因此,如果您的线程主函数如下所示:

 while (true) {
}

join() 将永远等待。

detatch() 也不会杀死线程。实际上它告诉 std::thread 即使 std::thread 对象被破坏,该线程也应该继续运行。 C++ 在 std::thread 析构函数中检查线程是加入还是分离,如果检查失败则终止程序。

因此,如果您取消注释以下代码的 main 函数中的第一行,它将崩溃。如果您取消注释第二行或第三行,它将正常工作。

 #include <thread>

void func() {
}

void fail1() {
    std::thread t(func);
    // will fail when we try to destroy t since it is not joined or detached
}

void works1() {
    std::thread t(func);
    t.join();
}

void works2() {
    std::thread t(func);
    t.detach();
}

int main() {
    // fail1();
    // works1();
    // works2();
}

原文由 Dmitry Ermolov 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题