線程函數(shù)的參數(shù)傳遞過程
- 參數(shù)從調(diào)用線程創(chuàng)建一份拷貝
- 執(zhí)行線程的拷貝變量拷貝到函數(shù)實(shí)參
驗(yàn)證:
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;
}
運(yùn)行結(jié)果
可以看出A對(duì)象的拷貝構(gòu)造函數(shù)調(diào)用了兩次. 了解這個(gè)過程的話就可以很好的判斷下面這個(gè)錯(cuò)誤
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;
}
這段代碼的行為是不確定的,分析線程函數(shù)參數(shù)的傳遞過程
- 數(shù)組地址進(jìn)行了一份拷貝,兩者指向同一塊內(nèi)容區(qū)
- 線程執(zhí)行,被拷貝的指針進(jìn)行數(shù)據(jù)類型轉(zhuǎn)化賦值給實(shí)參
這里重點(diǎn)是 線程啟動(dòng)。由于線程啟動(dòng)時(shí)機(jī)的不確定性,可能在第二次參數(shù)拷貝過程開始之前,先前的指針指向已失效,導(dǎo)致野指針錯(cuò)誤