c/c++ 多线程 等待一次性事件 异常处理

多线程 等待一次性事件 异常处理

背景:假设某个future在等待另一个线程结束,但是在被future等待的线程里发生了异常(throw一个异常A),这时怎么处理。

结果:假设发生了上面的场景,则在调用future的get方法时,就会得到被future等待的线程抛出的异常A。

3种情况:

1,std::async
2,std::packaged_task
3,std::promise,知道发生异常了,可以不调用set_value,而是调用set_exception(std::current_exception());
代码:
#include <iostream>
#include <string>
#include <future>

class A{
  int data;
public:
  A(int d = 10) : data(d){}
  int _data() const {return data;}
};
double div1(double a, double b){
  if(b == 0){
    //throw std::string("error");//进入string的catch
    //throw "error";//进入const char*的catch
    //throw 1;//进入int的catch
    throw A(101);//进入A a的catch
    
  }
  return a / b;
}

double div2(std::promise<double>& pro, double a, double b){
    int x;
    std::cin.exceptions (std::ios::failbit);   //如果不加这句,std::cin >> x这里,即使给的不是数字,也不会发生异常。
    try{
      std::cin >> x;//输入一个字母,就会引发异常
    }catch(std::exception&){
      pro.set_exception(std::current_exception());
    }

}
int main(){
  try{

    //std::asnyc 执行这段时,把后面的std::package_task和std::promise注释掉
    std::future<double> f = std::async(div1, 10, 0);
    std::cout << f.get() << std::endl;//get如果发生了异常,则进入catch

    //std::package_task 执行这段时,把std::asnyc和td::promise注释掉
    std::packaged_task<double(double, double)> t(div1);
    std::future<double> f2 = t.get_future();
    std::thread thread1(std::ref(t), 100, 0);
    thread1.detach();
    f2.get();//get如果发生了异常,则进入catch

    //std::promise 执行这段时,把上面的std::asnyc和td::package_task注释掉
    std::promise<double> pro;
    std::future<double> f3 = pro.get_future();
    std::thread thread2(div2, std::ref(pro), 100, 0);
    thread2.join();
    f3.get();get如果发生了异常,则进入catch(...)部分
    
  }
  catch(A a){
    std::cout << "err:A a" << std::endl;
    std::cout << a._data() << std::endl;
  }
  catch(int a){
    std::cout << "err:int" << std::endl;
    std::cout << a << std::endl;
  }
  catch(const char* s){
    std::cout << "err:char*" << std::endl;
    std::cout << s << std::endl;
  }
  catch(std::string s){
    std::cout << "err:string" << std::endl;
    std::cout << s << std::endl;
  }
  catch(...){
    using namespace std;
    cout << "...." << endl;
    
  }
}

github源代码

c/c++ 学习互助QQ群:877684253

1414315-20181106214320230-961379709.jpg

本人微信:xiaoshitou5854

转载于:https://www.cnblogs.com/xiaoshiwang/p/10023543.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值