欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-11 18:53:22
基本线程管理 join detach join:主线程等待被join线程结束后,主线程才结束。 detach:主线程不等待被detach线程。 问题1:子线程什么时点开始执行? std::thread t(fun);执行后,就开始执行了。 问题2:在哪里调用join或者detach 1,使用deta ......

基本线程管理 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();
}//  -------->④

知识点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

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

本人微信:xiaoshitou5854