std::thread — detach()
detach()的作用是将子线程和主线程的关联分离,也就是说detach()后子线程在后台独立继续运行,主线程无法再取得子线程的控制权,即使主线程结束,子线程未执行也不会结束。
当主线程结束时,由运行时库负责清理与子线程相关的资源。
应用例子:让一个文字处理应用同时编辑多个文档,让每个文档处理窗口拥有自己的线程,每个线程运行同样的代码,并隔离不同窗口处理的数据。
官方描述
将执行的线程与线程对象分离,允许独立地继续执行。一旦线程退出,任何分配的资源都会被释放。调用detach *后,它不再拥有任何线程。
#include <iostream>
#include <chrono>
#include <thread>
void independentThread()
{
std::cout << "Starting concurrent thread.\n";
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Exiting concurrent thread.\n";
}
void threadCaller()
{
std::cout << "Starting thread caller.\n";//首先执行主线程
std::thread t(independentThread);
t.detach();//线程分离
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Exiting thread caller.\n";
}
int main()
{
threadCaller();
std::this_thread::sleep_for(std::chrono::seconds(5));
}
//结果输出
Starting thread caller.
Starting concurrent thread.
Exiting thread caller.
Exiting concurrent thread.
detach()同时也带来了一些问题,如子线程要访问主线中的对象,而主线中的对象又因为主线程结束而被销毁时,会导致程序崩溃。所以传递参数时需要注意一些陷阱:
1、访问主线程对象以及指针问题
2、构造线程时隐式转换问题,子线程可以还来不及转换,主线程对象就销毁了,解决方法是构造线程时,构造一个临时对象传入
处理方法:
- 对于内置简单类型,建议传值;
- 对于类对象,建议使用引用来接收,以为使用引用会只会构造两次,而传值会构造三次;
- 在detach下要避免隐式转换,因为此时子线程可能还来不及转换主线程就结束了,应该在构造线程时,用参数构造一个临时对象传入。
- 指针绝不使用。
- 传递类对象时,形参为引用,实参为匿名对象。形参为引用是防止多次拷贝,实参为匿名对象是防止子线程拷贝之前主线程提前结束。
本文详细介绍了C++中std::thread的detach()函数,该函数用于将线程与线程对象分离,使线程在后台独立运行。在主线程结束后,运行时库会清理子线程资源。示例代码展示了detach()的应用,如在文字处理应用中处理多个文档。然而,detach()也带来了问题,如子线程访问已销毁的主线程对象,可能导致程序崩溃。因此,传递参数时需谨慎,避免使用指针,推荐使用内置类型或引用。总结了detach()使用时的陷阱和解决方法,包括传递参数的最佳实践。
1712

被折叠的 条评论
为什么被折叠?



