传递类对象以及智能指针作为线程参数(以detach()结尾)

结论:
当传递一个类对象作为线程参数时,不论是用字面值接受,还是用引用接受,
thread()都会将这个对象拷贝一份,所以我们在线程函数中修改这个对象,没法对主线程中的对象产生影响.

一.线程id

std::this_thread::get_id():获取线程id

二.经验
thread()+detach():给子线程传递参数时,使用临时对象作为参数,子线程函数的参数在主线程退出前构造出来,最后即使父子线程分离,也不用担心非法访问的问题.

void fun(const test&re)
{
	//dosomething
}
int main()
{
	//...
	int v = 100;
	thread t(fun,test(v));
	t.detach();
	//...
	return 0;
}

thread()+join():不用关心上述问题,所以能用join(),一定使用join().

三.std::ref 传递对象,detach()结尾

在第二点描述中,由于子线程将参数的内容进行了拷贝,所以如果我们在子线程函数中修改参数,将不会影响到主线程,但是有的时候我们是希望子线程中去修改某些数据.


实参是一个对象,形参用const引用接受,但是子线程中还是重新的将实参对象拷贝了一份
我们修改这个对象肯定不能引起主线程中这个对象的改动,这样下面这个函数应运而生.


std::ref 函数:明确的告诉编译器传递一个可以对主线程对象产生影响的引用,
而不是"假引用",还进行了拷贝构造,导致没法影响.


//线程函数中修改对象
 15 void thread_fun(const A&src)
 16 {
 17     src.v = 999;
 18 }
  //......
 23     A obj(m);                                                                                     
 24 
 25     thread t1(thread_fun,obj);

正确使用ref()函数:

 23     A obj(m);                                                                                     
 24 
 25     thread t1(thread_fun,std::ref(obj));
 //将不会调用拷贝构造函数,在线程函数中修改对象,即就是对主线程的对象产生影响

四.传递智能指针作为线程函数参数

使用智能指针,一定搭配join(),否则会产生内存的非法访问
因为以detach()结尾,主线程退出,智能指针释放内存,将会把内存还给OS
如果子线程继续访问,是个大BUG

unique_ptr<int> p(new int(998));
std::thread t1(thread_fun,std::move(p));

五.用成员函数指针作为线程函数

class A{
public:
	A(int m ):val(m){ //... }
	int m;
	void thread_fun(int m){ //... }  //该函数将作为线程运行函数
};
int main()
{
	A obj(10);
	thread obj(&A::thread_work,std::ref(obj),15);
	//第一个参数是成员函数
	//第三个参数开始才是真正给线程函数的参数
	obj.join();
	//一定用join(),如果不去修改对象
	//可以考虑用detach,因为也会将对象复制一份,不过也就不能用ref
	return 0;
}

调用拷贝构造,意味着可以使用detach,因为此时这份内存子线程函数也有一份
如果需要修改原来对象的值,那么就可以使用ref()函数,真正的去引用这个对象,但是此时不能使用detach.

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值