thread --- detach()的使用

本文详细介绍了C++中std::thread的detach()函数,该函数用于将线程与线程对象分离,使线程在后台独立运行。在主线程结束后,运行时库会清理子线程资源。示例代码展示了detach()的应用,如在文字处理应用中处理多个文档。然而,detach()也带来了问题,如子线程访问已销毁的主线程对象,可能导致程序崩溃。因此,传递参数时需谨慎,避免使用指针,推荐使用内置类型或引用。总结了detach()使用时的陷阱和解决方法,包括传递参数的最佳实践。

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、构造线程时隐式转换问题,子线程可以还来不及转换,主线程对象就销毁了,解决方法是构造线程时,构造一个临时对象传入

处理方法:

  1. 对于内置简单类型,建议传值;
  2. 对于类对象,建议使用引用来接收,以为使用引用会只会构造两次,而传值会构造三次;
  3. 在detach下要避免隐式转换,因为此时子线程可能还来不及转换主线程就结束了,应该在构造线程时,用参数构造一个临时对象传入。
  4. 指针绝不使用。
  5. 传递类对象时,形参为引用,实参为匿名对象。形参为引用是防止多次拷贝,实参为匿名对象是防止子线程拷贝之前主线程提前结束。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值