二、執行緒的啟動與結束 join與detach
阿新 • • 發佈:2021-09-15
主執行緒與子執行緒
預設情況下,主執行緒執行完後,那麼所有子執行緒也會結束,整個程式執行完畢;除非用detach()分離子執行緒與主執行緒。
Thread:一個標準庫中的類
join():阻塞主執行緒;加join() 的地方往往是主執行緒需要子執行緒的執行結果。
detach():分離子執行緒;當子程式很多時,讓主執行緒一直等不太好,子執行緒在執行完後會自動被C++執行時庫清理。
我們建議用join:阻塞主執行緒,讓子執行緒先執行完,再繼續執行主執行緒。
既然阻塞主執行緒了,那還有多執行緒的加速執行效果嗎?
有的,比如中間的迴圈(14~16行),這段程式碼是主執行緒和子執行緒並行執行的。
1#include <thread> 2 #include<iostream> 3 using namespace std; 4 5 void myprint() //自己建立的執行緒也要從一個函式開始執行 6 { 7 cout << "start thread" << endl; 8 cout << "end thread" << endl; 9 } 10 11 int main() { 12 //thread物件的建構函式接受的是一個可呼叫物件,建立了執行緒,執行緒執行起點myprint();13 thread myobj(myprint); 14 for (int i = 0; i < 100; i++) { 15 cout << "中間的程式碼" << endl; 16 } 17 // 阻塞主執行緒,讓主執行緒等待子執行緒執行完畢,然後主執行緒與子執行緒匯合繼續執行, 18 // 當子執行緒執行完畢,join()就執行完畢,主執行緒繼 續執行 19 myobj.join(); 20 cout << "good luck" << endl; 21return 0; 22 }
tip:一但呼叫了join()就不能再detach()了。
joinable():判讀是否可以成功join()或者detach()的。返回true時可以join或者detach,返回false時不行。
1 #include <thread> 2 3 vodi myprint() //自己建立的執行緒也要從一個函式開始執行 4 { 5 cout << "start thread" << endl; 6 cout << "end thread" << endl; 7 } 8 9 int main(){ 10 thread myobj(myprint); 11 12 if(myobj.joinable()){ //true 13 cout << "joinable() == ture" << endl; 14 } 15 16 myobj.detach(); 17 18 if(!myobj.joinable()){ //false 19 cout << "joinable() == false" << endl; 20 } 21 22 cout << "good luck" << endl; 23 return 0; 24 }
其他建立執行緒的方法:
總的原則:可呼叫物件作為執行緒入口。
1.用類的仿函式,可帶引數
1 class CT 2 { 3 public: 4 void operator()() //可呼叫物件 5 {} 6 }; 7 8 int main(){ 9 CT ct; 10 thread myobj(ct); 11 myobj.join(); 12 }
2.lambda表示式,泛型程式設計也是仿函式和lambda表示式成對出現
auto mylambda = [] (){ // [外部變數](返回值) cout << "lambda" << endl; } int main(){ thread myobj(mylambda); //myobj.join(); myobj.detach(); }
心之所願,永不相忘