C++ 我什么时候应该使用 std::thread::detach?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22803600/
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
When should I use std::thread::detach?
提问by Jinbom Heo
Sometime I have to use std::thread
to speed up my application. I also know join()
waits until a thread completes. This is easy to understand, but what's the difference between calling detach()
and not calling it?
有时我必须用来std::thread
加速我的应用程序。我也知道join()
等待线程完成。这很容易理解,但是调用detach()
和不调用有什么区别呢?
I thought that without detach()
, the thread's method will work using a thread independently.
我认为没有detach()
,线程的方法将独立使用线程工作。
Not detaching:
不分离:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called without detach");
});
//some code here
}
Calling with detaching:
调用分离:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called with detach");
});
t.detach();
//some code here
}
回答by Matthieu M.
In the destructor of std::thread
, std::terminate
is called if:
在 , 的析构函数中std::thread
,std::terminate
如果:
- the thread was not joined (with
t.join()
) - and was not detached either (with
t.detach()
)
- 该线程未加入(与
t.join()
) - 并且也没有分离(与
t.detach()
)
Thus, you should always either join
or detach
a thread before the flows of execution reaches the destructor.
因此,在执行流程到达析构函数之前,您应该始终选择一个线程join
或detach
一个线程。
When a program terminates (ie, main
returns) the remaining detached threads executing in the background are not waited upon; instead their execution is suspended and their thread-local objects destructed.
当程序终止(即main
返回)时,不等待在后台执行的剩余分离线程;相反,它们的执行被暂停并且它们的线程本地对象被破坏。
Crucially, this means that the stack of those threads is not unwoundand thus some destructors are not executed. Depending on the actions those destructors were supposed to undertake, this might be as bad a situation as if the program had crashed or had been killed. Hopefully the OS will release the locks on files, etc... but you could have corrupted shared memory, half-written files, and the like.
至关重要的是,这意味着这些线程的堆栈不会展开,因此不会执行某些析构函数。根据这些析构函数应该采取的行动,这可能是一个糟糕的情况,就像程序崩溃或被杀死一样。希望操作系统会释放对文件等的锁定……但您可能已经损坏了共享内存、写了一半的文件等。
So, should you use join
or detach
?
那么,你应该使用join
还是detach
?
- Use
join
- Unless you need to have more flexibility AND are willing to provide a synchronization mechanism to wait for the thread completion on your own, in which case you may use
detach
- 用
join
- 除非您需要更大的灵活性并且愿意提供一个同步机制来等待您自己的线程完成,在这种情况下您可以使用
detach
回答by 6502
You should call detach
if you're not going to wait for the thread to complete with join
but the thread instead will just keep running until it's done and then terminate without having the main thread waiting for it specifically.
detach
如果您不打算等待线程完成,则应该调用,join
但线程将继续运行直到完成,然后终止而无需主线程专门等待它。
detach
basically will release the resources needed to be able to implement join
.
detach
基本上会释放出能够执行所需的资源join
。
It is a fatal error if a thread object ends its life and neither join
nor detach
has been called; in this case terminate
is invoked.
如果一个线程对象结束它的生命并且既join
没有detach
被调用也没有被调用,这是一个致命错误;在这种情况下terminate
被调用。
回答by GreenScape
When you detach thread it means that you don't have to join()
it before exiting main()
.
当您分离线程时,这意味着您join()
在退出之前不必使用它main()
。
Thread library will actually wait for each such thread below-main, but you should not care about it.
线程库实际上会在 main 下等待每个这样的线程,但你不应该关心它。
detach()
is mainly useful when you have a task that has to be done in background, but you don't care about its execution. This is usually a case for some libraries. They may silently create a background worker thread and detach it so you won't even notice it.
detach()
当您有一个必须在后台完成的任务,但您不关心它的执行时,这主要是有用的。这通常是某些图书馆的情况。他们可能会默默地创建一个后台工作线程并将其分离,因此您甚至不会注意到它。
回答by user7860670
This answer is aimed at answering question in the title, rather than explaining the difference between join
and detach
. So when should std::thread::detach
should be used?
这个答案的目的是在标题答题,而不是解释之间的差异join
和detach
。那么应该std::thread::detach
什么时候使用呢?
In properly maintained C++ code std::thread::detach
should not be used at all. Programmer must ensure that all the created threads gracefully exit releasing all the acquired resources and performing other necessary cleanup actions. This implies that giving up ownership of threads by invoking detach
is not an option and therefore join
should be used in all scenarios.
在正确维护的 C++ 代码中std::thread::detach
根本不应该使用。程序员必须确保所有创建的线程优雅地退出,释放所有获取的资源并执行其他必要的清理操作。这意味着通过调用放弃线程的所有权detach
不是一种选择,因此join
应该在所有场景中使用。
However some applications rely on old and often not well designed and supported APIs that may contain indefinitely blocking functions. Moving invocations of these functions into a dedicated thread to avoid blocking other stuff is a common practice. There is no way to make such a thread to exit gracefully so use of join
will just lead to primary thread blocking. That's a situation when using detach
would be a less evil alternative to, say, allocating thread
object with dynamic storage duration and then purposely leaking it.
然而,一些应用程序依赖于可能包含无限期阻塞功能的旧的且通常设计和支持不佳的 API。将这些函数的调用移动到专用线程中以避免阻塞其他东西是一种常见的做法。没有办法让这样的线程优雅地退出,所以使用join
只会导致主线程阻塞。在这种情况下, usingdetach
将是一种不那么邪恶的替代方案,例如,分配thread
具有动态存储持续时间的对象然后故意泄漏它。
#include <LegacyApi.hpp>
#include <thread>
auto LegacyApiThreadEntry(void)
{
auto result{NastyBlockingFunction()};
// do something...
}
int main()
{
::std::thread legacy_api_thread{&LegacyApiThreadEntry};
// do something...
legacy_api_thread.detach();
return 0;
}
回答by DinoStray
According to cppreference.com:
Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.
After calling detach
*this
no longer owns any thread.
将执行线程与线程对象分开,允许独立继续执行。一旦线程退出,任何分配的资源都将被释放。
调用 detach 后
*this
不再拥有任何线程。
For example:
例如:
std::thread my_thread([&](){XXXX});
my_thread.detach();
Notice the local variable: my_thread
, while the lifetime of my_thread
is over, the destructor of std::thread
will be called, and std::terminate()
will be called within the destructor.
注意局部变量: my_thread
,当 of 的生命周期my_thread
结束时,std::thread
将调用of 的析构函数,并将在析构函数中调用std::terminate()
。
But if you use detach()
, you should not use my_thread
anymore, even if the lifetime of my_thread
is over, nothing will happen to the new thread.
但是如果detach()
使用my_thread
了,就不应该再使用了,即使 的生命周期my_thread
结束,新线程也不会发生任何事情。