目录
4.1引用和指针的陷阱
void myprint(const int &i, char *pmybuf)
{
cout << i << endl;
cout << pmybuf << endl;
}
int main()
{
int myva = 1;
int &myvary = myva;
char charbuf[] = "this my thread";
thread myTobj(myprint, myva, charbuf);
myTobj.detach();
cout << "Hello World!\n";
}
当对线程使用detach()时,有可能会出现主线程结束,但是子线程还没有执行结束,那么此时会出现一个问题:主线程结束后,变量myva以及charbuf会被销毁,那么子线程还可以正常使用吗
针对此问题的解答是:如果使用的是引用(例如myprint函数中的const int &i),那么子线程会将主线程中的变量复制过去,而不是直接引用原本的myva地址;如果使用的是指针(例如myprint函数中的char *pmybuf),那么子线程函数中的指针会指向原变量地址,那么此时会产生问题。
所以有的人会使用类型转换将char *pmybuf转换成string类型,这时会产生另外一个陷阱
4.2类型转换的陷阱
类型转换的陷阱:进行类型转换时,是在子线程接收变量时转换(如下)
void myprint(const int i, string &pmybuf)
{
cout << i << endl;
cout << pmybuf.c_str() << endl;
}
还是在主线程创建子线程传参时进行转换(如下)
char charbuf[] = "this my thread";
thread myTobj(myprint, myva, string(charbuf));
事实上,当只是使用在子线程中进行类型转换时,会出现主线程中的变量空间都已经被回收了,子线程才开始进行类型转换,此时会出现问题。
4.3总结
a)在传递int等简单类型时,尽量使用值传递,尽量不适用引用
b)在传递类对象时尽量避免隐式类型转换,要在创建线程的时候同时构造临时对象来传递参数,然后在函数参数里,使用引用来接受临时对象。
c)尽量使用join(),不建议使用detach()。