Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 506|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-8-30 11:43:05 | 显示全部楼层 |阅读模式

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

    背景:假设某个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

    本人微信:xiaoshitou5854

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 05:01 , Processed in 0.051690 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表