有时候我不得不使用std::thread
来加速我的应用程序。我也知道join()
会等待一个线程完成。这很容易理解,但是调用detach()
和不调用它有什么区别呢?
我认为如果没有detach()
,线程的方法将独立使用线程。
未分离:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called without detach");
});
//some code here
}
使用分离调用:
void Someclass::Somefunction() {
//...
std::thread t([ ] {
printf("thread called with detach");
});
t.detach();
//some code here
}
6条答案
按热度按时间14ifxucb1#
在
std::thread
的析构函数中,如果:t.join()
)t.detach()
)因此,在执行流到达析构函数之前,您应该总是
join
或detach
线程。当一个程序终止时(即
main
返回),其余在后台执行的分离线程不会被等待;而是挂起它们的执行,并且不析构它们的线程局部对象。关键的是,这意味着 * 这些线程的堆栈没有被展开 *,因此一些析构函数没有被执行。根据这些析构函数应该执行的操作,这可能是一个糟糕的情况,就像程序崩溃或被杀死一样。希望操作系统会释放对文件的锁定等...但你可能已经损坏了共享内存,半写文件等。
那么,应该使用
join
还是detach
呢?join
detach
kh212irz2#
如果你不打算等待线程完成
join
,但线程会一直运行,直到它完成,然后在没有spawner线程等待它的情况下终止,那么你应该调用detach
;例如:detach
基本上将释放实现join
所需的资源。如果一个线程对象结束了它的生命,并且
join
和detach
都没有被调用,这是一个致命错误;在这种情况下,调用terminate
。ee7vknir3#
这个答案是为了回答标题中的问题,而不是解释
join
和detach
之间的区别。那么什么时候应该使用std::thread::detach
呢?在正确维护的C++代码中,根本不应该使用
std::thread::detach
。程序员必须确保所有创建的线程正常退出,释放所有获取的资源并执行其他必要的清理操作。这意味着通过调用detach
放弃线程所有权不是一个选项,因此join
应该在所有场景中使用。然而,一些应用程序依赖于旧的,通常没有很好设计和支持的API,这些API可能包含无限期阻塞的函数。将这些函数的调用移动到专用线程以避免阻塞其他内容是一种常见的做法。没有办法使这样的线程优雅地退出,所以使用
join
只会导致主线程阻塞。在这种情况下,使用detach
将是一个不那么邪恶的替代方案,比如说,为thread
对象分配动态存储时间,然后故意泄漏它。ohfgkhjo4#
当你分离线程时,这意味着你在退出
main()
之前不必join()
它。detach()
主要用于当你有一个任务需要在后台完成,但你不关心它的执行。这通常是一些库的情况。他们可能会默默地创建一个后台工作线程并分离它,所以你甚至不会注意到它。s8vozzvw5#
根据cppreference.com:
将执行线程与线程对象分离,允许执行独立地继续。一旦线程退出,任何分配的资源都将被释放。
调用detach后,
*this
不再拥有任何线程。例如:
注意局部变量:
my_thread
,当my_thread
的生存期结束时,将调用std::thread
的析构函数,并在析构函数中调用std::terminate()
。但是如果你使用
detach()
,你就不应该再使用my_thread
了,即使my_thread
的生存期结束了,新线程也不会发生任何事情。wkftcu5l6#
也许这是一个好主意,重复上面的答案中提到的内容:当main函数完成并且主线程关闭时,所有的spawn线程都会被终止或挂起。所以,如果你依靠detach让后台线程在主线程关闭后继续运行,你会感到惊讶。要查看效果,请尝试以下操作。如果你取消注解最后一个sleep调用,那么输出文件将被创建并写入fine。否则不会: