C++-std::thread之向线程函数传递参数

向线程函数传递参数

向线程函数传递参数只需要向std::thread构造函数传递额外的参数即可

std::thread t(hello,arg1,arg2);

需要注意的是,参数会被拷贝到单独的存储空间中,然后作为右值传递给可调用对象

void f(int i,std::string const& s);
std::thread t(f,3,"hello");

这里"hello"作为const char *传递给构造函数,并且只在新线程的上下文中转换为string类型,这可能会导致某些错误:

void f(int i,std::string const& s);
void oops(int some_param)
{
    char buffer[1024]; 
    sprintf(buffer, "%i",some_param);
    std::thread t(f,3,buffer); 
    t.detach();
}

这里buffer作为char *类型被拷贝到内部存储空间,很有可能在buffer转化为string之前,opps函数就退出了,这时进入新线程上下文,char *被转化为string类型传递给f,此时buffer内容不确定,转为string会导致未定义的行为。

解决方案是提前转化过程:

std::thread t(f,3,std::string(buffer)); 

由于拷贝后的值是右值,如果函数参数是左值引用,那么会导致编译错误,因为不能将一个右值传递给期望左值引用参数的函数,解决方法是使用std::ref函数

void update_data_for_widget(widget_id w,widget_data& data); 
void oops_again(widget_id w)
{
    widget_data data;
    std::thread t(update_data_for_widget,w,std::ref(data)); 
    t.join();
}

当我们希望传递一个对象(这里的data)而又不拷贝它,就必须使用标准库函数ref,ref返回一个对象,包含给定的引用,此对象是可拷贝的
类似的,如果函数参数不能被拷贝只能被移动,如std::unique_ptr,那么创建线程传递参数时,如果传递进去的就是右值,那么移动相关函数会被自动调用,如果不是右值,那么需要显示调用std::move

void process_big_object(std::unique_ptr<big_object>);
std::unique_ptr<big_object> p(new big_object);
p->prepare_data(42);
std::thread t(process_big_object,std::move(p));

std::thread的所有权机制跟std::unique_ptr一样,虽然没有动态分配的对象,但std::thread负责管理一个线程的执行,线程的所有权可以在thread对象之间转移,但不能拷贝。这意味着一个thread对象只和一个线程关联

void hello()
{
	cout << "Hello Concurrent World!";
}

void delayHello()
{
	Sleep(3000);
	cout << "Deley Hello Concurrent World!";
}
thread t(delayHello);
thread t2(hello);
t2.join();//等待hello线程退出
t2 = std::move(t);//delayHello线程从t对象转到t2
cout << "delayHello "<<t2.joinable()<<endl;
t2.join();//等待delayHello线程退出
  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrbone11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值