執行緒傳參,detach的大坑,成員函式做執行緒函式
阿新 • • 發佈:2018-12-21
傳遞臨時物件作為引數
VS shitf+F9
檢視變數
void myprint(const int &t, char *j) { cout << t << endl; cout << j << endl; } int main() { int m=1; int &n = m; char mybuf[] = "hello world"; std::thread mythred(myprint, n, mybuf); //mythred.join(); mythred.detach(); return 0; }
指標在detach中絕對有問題,傳引用也是傳的複製。
class A { public: A() { cout << "建構函式執行" << endl; } ~A() { cout << "解構函式執行" << endl; } A(const A &b) { cout << "拷貝建構函式執行" << endl; } }; void myprint(int i, const A &a) { cout << i << endl; cout << &a << endl; } int main() { int m=1; int &n = m; A a; std::thread mythred(myprint, n, a); mythred.detach(); return 0; }
其中,傳已有變數的時候,A的解構函式只執行了一次。
class A { public: A() { cout << "建構函式執行" << endl; } ~A() { cout << "解構函式執行" << endl; } A(const A &b) { cout << "拷貝建構函式執行" << endl; } }; void myprint(int i, const A &a) { cout << i << endl; cout << &a << endl; } int main() { int m=1; std::thread mythred(myprint, m, A(a)); mythred.detach(); return 0; }
所以,要傳物件得使用臨時物件。因為臨時物件是在主執行緒中建立的。
(1)若傳的是簡單引數,直接值傳遞,不要用引用。
(2)如果傳遞的是類物件,避免隱式型別轉換。然後在函式引數裡面,採用引用傳參,否則,還會多一次拷貝構造。
所以,detach()有什麼好。
執行緒ID:get.id()
class A {
public:
mutable int i;
A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
~A() { cout << "解構函式執行" << endl; }
A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint( const A &a)
{
a.i = 100;
cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
A a(10);
std::thread test(myprint, a);
test.join();
return 0;
}
即時傳入的是引用,但是也不會修改源物件的值,因為修改的地址不同,為了資料的安全考慮,往執行緒傳遞類型別,編譯器會統一按照拷貝的方式。
std::ref :傳遞物件,而不是拷貝。
class A {
public:
mutable int i;
A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
~A() { cout << "解構函式執行" << endl; }
A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(A &a)
{
a.i = 100;
cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
A a(10);
std::thread test(myprint, std::ref(a));
test.join();
return 0;
}
std::move() 智慧指標線上程中的傳遞
class A {
public:
mutable int i;
A(int j):i(j) { cout <<"i="<<i<< "建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
~A() { cout << "解構函式執行" << endl; }
A(const A &b):i(b.i) { cout << "i=" << i << "拷貝建構函式執行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(unique_ptr<A>a)
{
a->i = 100;
cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
unique_ptr<A> a(new A(10));
std::thread test(myprint, std::move(a));
test.join();
return 0;
}
而且絕對不能detach()。
用成員函式作為執行緒函式。