线程函数的参数传递过程
- 参数从调用线程创建一份拷贝
- 执行线程的拷贝变量拷贝到函数实参
验证:
class A {
public:
A() { cout << "A::A()" << endl; }
A(A const&) { cout << "A::A(A const&)" << endl; }
};
void thread_func(A a)
{
//do_something_with_a...
}
int main(int argc, char const*argv[])
{
A a;
thread(thread_func, a).join();
return 0;
}
可以看出A对象的拷贝构造函数调用了两次. 了解这个过程的话就可以很好的判断下面这个错误
void handle_msg(string const&msg)
{
this_thread::sleep_for(2s);
cout << msg.c_str() << endl;
}
int main(int argc, char const*argv[])
{
{
char buf[]{ "message" };
thread(handle_msg, buf).detach();
}
getchar();
return 0;
}
这段代码的行为是不确定的,分析线程函数参数的传递过程
- 数组地址进行了一份拷贝,两者指向同一块内容区
- 线程执行,被拷贝的指针进行数据类型转化赋值给实参
这里重点是 线程启动。由于线程启动时机的不确定性,可能在第二次参数拷贝过程开始之前,先前的指针指向已失效,导致野指针错误