线程传参详解,detach的坑

本文探讨了C++中线程安全的实现方法,重点介绍了如何正确传递参数以避免线程间的数据竞争,并讨论了使用std::ref的风险及推荐做法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include<thread>
#include<string>
using namespace std;

//线程id:每个线程都有一串唯一的数字来标识,这串数字就是线程id。可通过std::this_thread::get_id()来获取。

//detach时
//1.如果传递int这种简单类型参数,建议都是值传递,不要用引用(可能会发生调用已释放的内存的情况)
//2.如果传递类对象,避免隐式类型转换,在创建线程时就构造临时对象,然后在函数参数里,最好用引用来接。(否则会拷贝构造两次)
//3.std::ref
//建议少使用detach,多使用join,这样就不存在局部变量失效导致线程对内存非法访问的问题

//void myprint(const int & i, char *pmybuf)
void myprint(const int  i, const string pmybuf)  //这样修改后可避免指向相同地址的问题,但在char数组转为string前可能就被系统回收了(主线程执行完毕)
{
 	cout << i << endl;   //分析认为,i并不是mvar的引用,实际是值传递(复制,i和mvar的地址不一样)。那么可以认为,即使主线程detach了子线程,子线程的i依旧是安全的
	cout << pmybuf << endl;  //指针在detach时是绝对有问题的,所指的地址是相同的
	return;
}
int main()
{
	//1.传递临时对象作为线程参数
	int mvar = 1;
	int &mvary = mvar;
	char mybuf[] = { "this is a test" };
	thread mytobj(myprint, mvar, mybuf);  //事实上,detach时,存在mybuf都被回收了(main函数执行完了),系统才用mybuf去转string的可能性(因为是在子线程中构造string对象)
	thread mytobj(myprint, mvar, string(mybuf)); //直接将mybuf转换为string临时对象,这样可以保证线程中的mybuf一定有效(主线程中构造string对象,稳定)
	thread mytobj(myprint, mvar, std::ref(mybuf));  //这样线程引用中的修改的值可影响到主线程的值(两个地址相同,不调用拷贝构造函数,那么detach时可能就会不安全(内存非法访问))  std::ref(mybuf)==&mybuf
	//mytobj.join();
	mytobj.detach();
	cout << "主线程执行1" << endl;

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值