VC中vc 线程传递参数函数如何传递多个参数

豆丁微信公众号
君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
C_多线程函数如何传参数和返回值
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口管理线程之向线程函数传递参数
向线程函数传递参数在构造线程对象时即可完成。但是要记住,默认情况下是把参数拷贝到线程内部,即使在函数中使用的是引用。例如
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& s);
void oops(int some_param)
char buffer[1024];
sprintf(buffer,"%i",some_param);
std::thread t(f,3,buffer);
t.detach();
}在这种情况下,指针指向局部变量buffer,然后传递到新创建的线程。很可能会发生函数oops已经终止,但是buffer还没有转换为std::string,这是buffer已经销毁。解决的方法就是在传递之前就转换:
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();
}这是,依赖buffer想std::string的隐式转换,之后作为函数参数
可能会出现和上面相反的情况:线程拷贝了对象实例,但是你想要传递引用。在使用引用传递参数,线程更新数据时:
void update_data_for_widget(widget_id w,widget_data& data);
void oops_again(widget_id w)
std::thread t(update_data_for_widget,w,data);
display_status();
process_widget_data(data);
}尽管update_data_for_widget希望第二个参数用引用传递,但是std::thread的构造函数不知道,这是函数的参数会被拷贝。当调用update_data_for_widget时,会传递拷贝data的引用,而不是data的引用。当线程终止,线程内部的拷贝析构,但是函数process_widget_data传递的是未更新的data。对于熟悉std:bind的人来说,马上就能想到解决的办法:你需要使用std::ref包装参数。需要更改线程创建形式为:
std::thread t(update_data_for_widget,w,std::ref(data));如果你熟悉std::bind,参数传递的语法就容易理解。因为std::thread的构造函数和std::bind都是使用同样的原理。这也就是说,你可以传递成员函数的指针作为函数参数,假如你使用对象指针作为第一个参数。
void do_lengthy_work();
std::thread t(&X::do_length_work,&my_x);上面代码会在新线程调用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));
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!下次自动登录
现在的位置:
& 综合 & 正文
在VC中如何创建多个线程
在VC中如何创建多个线程
在工作中我们经常会遇到要建立多个线程,以此方便于我们可以同时执行多个事件。这也是我们在VC开发中的一项基础,虽然我曾多次用到,但也会常常忘记。这次记下来,作为一个笔记,为大家学习提供方便。在VC中,无非是创建线程和写线程函数1,
创建线程:#include &windows.h&在MFC中通常在OnInitDialog()下面创建线程//定义参数:SerialControl//------------------变量函数初始化调用区域--------
CSerialControl * m_SerialControl=new CSerialControl(); m_SerialControl-&Create(NULL,"aa",WS_CHILD,CRect(0,0,0,0),this,2,NULL);
m_SerialControl-&InitAllSerialPort();//------------------------------------------------ HANDLE hThread1=CreateThread(NULL,0,DetectCar,(LPVOID)SerialControl,0,NULL);CloseHandle(hThread1);//此处关闭线程的句柄,但不意味关闭线程,线程在程序退出时关闭参数说明:HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,//必须为NULL DWORD dwStackSize, //一般为0 ,表示堆栈与外部大小相同LPTHREAD_START_ROUTINE lpStartAddress, //线程函数名称LPVOID lpParameter, //传递给线程函数的参数,如果为多个,自定义结构体DWORD dwCreationFlags, //0表示创建线程后立即启动线程,如果不是立即启动需要调用ResumeThread函数LPDWORD lpThreadId);//用来标记该线程的名称 2,
定义线程函数://函数的定义static
DWORD WINAPI DetectCar(LPVOID lpParameter); //一般用静态函数//remark:由于线程函数是静态函数,如果要在函数中用到对象,必须通过//函数的实现/****************************************************作者:万田*时间:*函数:DetectCar() 说明:检测线程****************************************************/DWORD WINAPI CISSDlg::DetectCar(LPVOID lpParameter){
TRACE("Thread DetectCar is running/r/n");
CSerialControl* SControl=(CSerialControl*)lpP
//define:record which road is car
int Carexit=0;
while (TRUE)//do this forever
//get:which road exit car
Carexit=SControl-&m_GroudDetector1.CarExists();
***********
【上篇】【下篇】VC++ 如何创建一个线程并传递参数
近来做个项目需要写点程序,比较烦.net写的老是需要背着.net包走,所以准备用VC++来写,其中用到了线程方面的知识这里记录下来以备后用。
创建一个工作线程十分简单,只需要两步你的线程就能跑了:(1)实现线程函数和(2)开始线程。不需要由CWinThread派生类,你可以不加修改地使用CWinThread。下面我们来看看如何开始一个线程。
AfxBeginThread有两种形式,一种是用来创建用户界面线程的,另一种就是用来创建工作线程的。为了开始执行你的线程,只需要向AfxBeginThread提供下面的参数就可以了:
线程函数的地址
传送到线程函数的参数
(可选的)线程的优先级,默认的是平常的优先级,如果希望使用其它优先级请参阅::SetThreadPriority
(可选的)线程的堆栈大小,默认的大小是和创建线程的堆栈一样大
(可选的)如果用户创建的线程在开始的时候在挂起态,而不在运行态,可以设置为CREATE_SUSPENDED
(可选的)线程的安全属性,默认的是和父线程的访问权限一样,有关安全信息的格式,请参阅SECURITY_ATTRIBUTES
AfxBeginThread为用户创建并初始化一个CWinThread对象,运行这个对象,并返回它的地址,这样通过这个地址用户就可以找到它了。在这一过程中还要进行许多检查。这一切都不用你操心。那么下面我们来看看线程函数怎么写。线程函数定义了线程要做什么,在进入这个函数的时候线程开始,退出的时候线程结束。这个函数必须是下面的形式:
MyControllingFunction(
参数是一个32位数,这个参数在线程对象创建时传送给对象的构造函数。至于线程函数要怎么处理这个数,那就随便了,它可能是一个人的年纪,可能是一个文件的地址,可能是一个窗口句柄,反正你想它是什么就是什么,主动权在你手里。如果参数指的是一个结构,结束可以用来向线程传送参数,也可以让线程把结果传回主程序,线程需要通知主程序,什么时候来取结果。
在线程函数结束时,应该返回一个UINT类型的值,说明返回原因,也就是返回代码。通常这个数为0,表示正常返回,当然你也可以定义一个错误编码指示错误了。至于什么数代表什么,全在你。下面是一个线程函数的例子,这个例子解释如何定义线程函数,也介绍了如何从程序的其它地方控制线程:(为了了解线程的全部,请安心阅读其它文章)
MyThreadProc(
CMyObject*
(CMyObject*)pP
||!pObject-&IsKindOf(RUNTIME_CLASS(CMyObject)))
successfully
pNewObject
AfxBeginThread(MyThreadProc,
pNewObject);
上面的例子是MSDN上写的,下面我还写个简单的,主函数传递参数给线程函数,并且线程函数返回值。
void CNEWDLG::CreateNewThread()
CString s="hello";
AfxBeginThead(WorkThread,&s);//这里的参数&s完全可以改成你需要的其他类型的地址,实现你的操作。
Sleep(1000);
MessageBox(s,NULL,0);
线程函数:
UINT WorkThread(LPVOID pParam) //偶觉得关键是这个参数,它可以传递任何类型。
CString* s1=(CString*)pP //不管你传递的是什么类型,都可以通过这种方式转换后使用。
*s1=" s has been changed!";
保存后运行,你会发现s已经被改成"s has been changed!"。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 java 线程 传递参数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信