c/c++ 基本線程管理 join detach


基本線程管理 join detach

join:主線程等待被join線程結束后,主線程才結束。

detach:主線程不等待被detach線程。

問題1:子線程什么時點開始執行?

std::thread t(fun);執行后,就開始執行了。

問題2:在哪里調用join或者detach

1,使用detach的話,直接在std::thread t(fun);后面加上t.detach()即可

2,使用join的話,就要自己選擇在代碼的哪個位置調用join。因為在子線程開始之后,但又在join被調用之前發生了異常,所以join的調用就沒有實際發生。

解決方案1:使用try catch

void f(){
  std::thread t(my_func);
  try{
    do_some_work();      
  }
  catch{
    t.join();
    throw;
  }
  t.join();
}

解決方案2:使用一個類包裝thread對象,在這個類的析構函數里調用join。

#include <iostream>
#include <thread>

using namespace std;

class my_thread{
public:
  explicit my_thread(thread& t_):t(t_){}
  ~my_thread(){
    if(t.joinable()){ //  -------->①
      t.join();//  -------->②
    }
  }
  my_thread(my_thread const&) = delete;//  -------->③
  my_thread& operator=(const my_thread&) = delete;
private:
  thread& t;
};

class func{
public:
  int& data;
  func(int& d):data(d){}
  void operator()(){
    cout << "thread started@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;
    for(unsigned j = 0; j < 100; ++j){
      cout << j << endl;
    }
  }
};

int main(){
  int state = 0;
  func f(state);
  thread t(f);
  my_thread mt(t);

  //do_something_in_current_thread();
}//  -------->④

github源代碼

知識點1:當程序執行到④處時,局部對象會被銷毀,所以mt的析構函數就會被調用。即使在do_something_in_current_thread();處發生異常了,mt的析構函數也會被調用,所以,join函數不管在什么情況下都會被調用。

知識點2:在②處調用join前,必須要先判斷是不是joinable①。這很重要,因為只能join一次,多次join就會出下面錯誤。

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument
Aborted (core dumped)

知識點3:拷貝構造函數和賦值運算符被標記成delete了③,一確保它們不會被編譯器自動提供。復制或賦值一個thread對象是很危險的,因為它可能比它要結合的線程的作用域存在更久。

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM