zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    hdu--1026--Ignatius and the Princess I(bfs搜索+dfs(打印路径))
    hdu--1798--Doing Homework again(贪心)
    开启事务的两种方法
    事务的隔离级别,乐观锁,悲观锁
    树的结构,无限极关联
    微信小程序的加密解密以及小程序的支付
    微信小程序之登录连接django,以及用户的信息授权认证
    微信小程序三
    微信小程序二
    vue-cookies缓存
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9752001.html
Copyright © 2011-2022 走看看