向线程函数传递参数

向线程函数传递参数在构造线程对象时即可完成。但是要记住,默认情况下是把参数拷贝到线程内部,即使在函数中使用的是引用。例如

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

上面代码中,函数f的第二个参数是std::string,传递的是char const *会转换为string。

当使用指针指向自动变量时,要特别注意:

<span style="font-size:14px;">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();
}</span>

在这种情况下,指针指向局部变量buffer,然后传递到新创建的线程。很可能会发生函数oops已经终止,但是buffer还没有转换为std::string,这是buffer已经销毁。解决的方法就是在传递之前就转换:

<span style="font-size:14px;">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,std::string(buffer));
	t.detach();
}</span>

这是,依赖buffer想std::string的隐式转换,之后作为函数参数

可能会出现和上面相反的情况:线程拷贝了对象实例,但是你想要传递引用。在使用引用传递参数,线程更新数据时:

<span style="font-size:14px;">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,data);
	display_status();
	t.join();
	process_widget_data(data);
}</span>

尽管update_data_for_widget希望第二个参数用引用传递,但是std::thread的构造函数不知道,这是函数的参数会被拷贝。当调用update_data_for_widget时,会传递拷贝data的引用,而不是data的引用。当线程终止,线程内部的拷贝析构,但是函数process_widget_data传递的是未更新的data。对于熟悉std:bind的人来说,马上就能想到解决的办法:你需要使用std::ref包装参数。需要更改线程创建形式为:

<span style="font-size:14px;">std::thread t(update_data_for_widget,w,std::ref(data));</span>

如果你熟悉std::bind,参数传递的语法就容易理解。因为std::thread的构造函数和std::bind都是使用同样的原理。这也就是说,你可以传递成员函数的指针作为函数参数,假如你使用对象指针作为第一个参数。

<span style="font-size:14px;">class X
{
	public:
		void do_lengthy_work();
};
X my_x;
std::thread t(&X::do_length_work,&my_x);</span>

上面代码会在新线程调用my_x.do_lengthy_work(),因为my_x的地址作为对象指针。你也可以提供参数例如成员函数调用:std::thread的第三个参数将会成为成员函数的第一个参数。

还有一种情况是函数参数对象不能拷贝,只能转移其所有权(例如STL中的auto_ptr指针)。std::unique_ptr就是这样的一个例子。std::unique指针一次只能指向一个对象,当指针析构时,对象也就被析构了。在赋值时是转移所有权(像auto_ptr)。在使用时,当对象是临时对象时,会自动调用move,当是个变量时必须调用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));
时间: 2024-10-29 19:05:43

向线程函数传递参数的相关文章

Net线程足迹 传递参数至线程

方法一:应用ParameterizedThreadStart这个委托来传递输入参数,这种方法适用于传递单个参数的情况. [c-sharp] view plaincopy using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using Sys

Jmeter 跨线程组传递参数 之两种方法

终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直到登录接口的参数失效了,需再次发送一次登录接口,又可以多次使用其参数,下面举例子: 1.登录接口中利用 Json Path Extractor 获取到登录接口的响应参数,(怎么获取上一节讲过) 终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为

js中函数传递参数,究竟是值传递还是引用传递?

记住真理: js函数传递参数,不管是简单数据类型,还是引用数据类型,都是值传递!! 下面是js红包书里面的例子: function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); // "Nicholas" 肯定

Delphi过程、函数传递参数的八种方式

Delphi过程函数传递参数的八种方式 Delphi过程.函数传递参数的八种方式,布布扣,bubuko.com

管理线程之向线程函数传递參数

向线程函数传递參数在构造线程对象时就可以完毕.可是要记住,默认情况下是把參数复制到线程内部,即使在函数中使用的是引用.比如 void f(int i,std::string const &s); std::thread t(f,3,"hello"); 上面代码中,函数f的第二个參数是std::string,传递的是char const *会转换为string. 当使用指针指向自己主动变量时.要特别注意: void f(int i, std::string const&

给wxPython事件处理函数传递参数

给wxPython事件处理函数传递参数 2014-04-30 07:47:08segmentfault-博客--点击数:39 最近捣鼓Python,也就自然捣鼓上了wxPython.我曾经用过Qt和Gtk+写GUI,但几乎所有的Python书都告诉我说最好用的是wxPython,我没有尝试PyQt和PyGtk就开始研究wxPython了.在Qt和Gtk+之间我更喜欢Qt,因为它跨平台做得很好,而且商业化也不错.但wxWidget给人的感觉就完全不同了. 如果说wxWidgets相对于Qt有什么优

javascript如何给事件处理函数传递参数

javascript如何给事件处理函数传递参数:在应用中可能需要给注册的事件处理函数传递参数,但是会发现好像无法实现直接传递,下面就简单介绍一下如何给事件处理函数传递参数.先看一段代码实例: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/&

[存]Jmeter 如何实现跨线程组传递参数

此文来源与组里小白的分享~ Jmeter 如何实现跨线程组传递参数(以传递token为例)   1.首先选择一个登陆接口(线程组1),添加正则表达式提取器提取token,接着再添加一个后置处理器BeanShell PostProcessor 2.BeanShell PostProcessor中参数项输入引用变量${token};脚本项输入动作语句${__setProperty(token1,${token},)}; 3.在线程组2添加一个前置处理器BeanShell PreProcessor 4

js函数传递参数时,如果是路径类型的参数,里边包含:&#39;\&#39;字符报错

在函数中,传递的参数中有“\”字符,js会将它默认为转义字符串,如果没有出现与他匹配的转义字符串,就会缺失,例如: 将这样的一个字符串作为一个参数:C:\Program Files (x86)\MySQL\MySQL Server 5.7\data\ 传递到函数里边的值就会被默认转化为:C:Program Files (x86)MySQLMySQL Server 5.7data 如果要实现这个参数的精确传递,就需要将字符串进行处理,一般会有两种方式: ①:将字符串里边的 ‘\’ 字符替换成 ‘/