C++多线程传参的三种方式
- 传入普通参数
- 传入引用
- 传入指针(不使用,因为如果主线程的资源被释放,那么子线程将会发生错误)
1. 传入普通的参数
普通参数传入线程是进行一份拷贝。对于类对象会调用拷贝构造函数。
void threadFunction(int x, string str) {
cout << &x <<endl;
cout << "x is " << x << " and str is " << str << endl;
return;
}
int main(int argc, char* argv[]) {
int x = 3;
cout << &x <<endl;
string str("hello");
thread myThread(threadFunction,x, str);
myThread.join();
cout << "EXIT!!!" << endl;
return 0;
}
现在考虑,如何将一个char[]
字符数组传入子线程。如果使用如下代码:
void threadFunction(const string &pmybuf){
cout<<pmybuf.c_str()<<endl;
}
int main(){
char mybuf[]=“this is a test”;//定义一个字符数组
thread mytobj(threadFunction,mybuf);
mytobj.join();//等待子线程执行完毕
return 0;
}
thread mytobj(threadFunction,mybuf);
启动这个线程,希望将mybuf
字符数组转化为字符串,然后再string
对象再被使用。这样主线程执行完毕,pmybuf
也存在。但现在是字符数组什么时候转为string
如果是主线程执行完毕后转,就会发生错误。为了解决这个问题可以先生成临时对象
thread mytobj(threadFunction,string(mybuf));
2. 传入引用
传入因为的参数一定要定义为const
不然会报错,不知道问题在哪里。
void threadFunction(const int &x, const string& str) {
cout << &x << endl;
cout << &str << endl;
cout << "x is " << x << " and str is " << str << endl;
return;
}
int main(int argc, char* argv[]) {
int x = 3;
cout << &x << endl;
string str("hello");
cout << &str << endl;
thread myThread(threadFunction,x, str);
myThread.join();
cout << "EXIT!!!" << endl;
return 0;
}
可以看到即使线程函数void threadFunction(const int &x, const string& str)
接受了引用作为参数,但是传入线程之后也生成了新的对象。这是因为线程函数threadFunction
中的对象是在新线程堆栈中复制的临时值的引用。为了确实使用主线程中的引用,可以使用std::ref()
函数。
thread myThread(threadFunction,ref(x), ref(str));
此时也不需要加const
thread obj(&A::thread_work, obj, 15);//函数指针,对象,值&obj == std::ref(obj)