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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37015775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:40:14  来源:igfitidea点击:

What is different between join() and detach() for multi threading in C++?

c++multithreadingc++11joindetach

提问by r.hg

What is different between join()and detach()in multi threading in C++? Does join()kill the thread?

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

回答by Michael Burr

A C++ threadobject generally (but not always) represents a thread of execution, which is an OS or platform concept.

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

When thread::join()is called, the calling thread will block until the thread of execution has completed. Basically, this is one mechanism that can be used to know when a thread has finished. When thread::join()returns, the OS thread of execution has completed and the C++ threadobject can be destroyed.

thread::join()被调用时,调用线程将阻塞,直到执行线程已经完成。基本上,这是一种可用于知道线程何时完成的机制。当thread::join()返回时,执行的OS线程已完成和C ++thread对象可以被破坏。

The thread::detach()is called, the thread of execution is "detached" from the threadobject and is no longer represented by a threadobject - they are two independent things. The C++ threadobject can be destroyed and the OS thread of execution can continue on. If the program needs to know when that thread of execution has completed, some other mechanism needs to be used. join()cannot be called on that threadobject any more, since it is no longer associated with a thread of execution.

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

It is considered an error to destroy a C++ threadobject while it is still "joinable". That is, in order to destroy a C++ threadobject either join()needs to be called (and completed) or detach()must be called. If a C++ threadobject is still joinable when it's destroyed, an exception will be thrown.

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

Some other ways that a C++ threadobject will not represent a thread of execution (ie., can be unjoinable):

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

  • A default constructed threadobject does not represent a thread of execution, so is not joinable.
  • A thread that has been moved from will no longer represent a thread of execution, so is not joinable.
  • 默认构造的thread对象不代表执行线程,因此不可连接。
  • 已移出的线程将不再代表执行线程,因此不可连接。

回答by dim-an

join()doesn't kill the thread. Actually it waits until thread main function returns. So if your thread main function looks like this:

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

while (true) {
}

join()is going to wait forever.

join()将永远等待。

detatch()doesn't kill thread either. Actually it tells std::threadthat this thread should continue to run even when std::threadobject is destroyed. C++ checks in std::thread destructor that thread is either joined or detached and terminates program if this check fails.

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

So if you uncomment first line in mainfunction of the following code it will crash. If you uncomment second or third line it will work ok.

因此,如果您取消注释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();
}