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

本人微信:xiaoshitou5854

原文地址:https://www.cnblogs.com/xiaoshiwang/p/10023543.html

时间: 2024-07-31 23:06:00

c/c++ 多线程 等待一次性事件 异常处理的相关文章

c/c++ 多线程 等待一次性事件 packaged_task用法

多线程 等待一次性事件 packaged_task用法 背景:不是很明白,不知道为了解决什么业务场景,感觉std::asynck可以优雅的搞定一切,一次等待性事件,为什么还有个packaged_task. 用法:和std::async一样,也能够返回std::future,通过调用get_future方法.也可以通过future得到线程的返回值. 特点: 1,是个模板类,模板类型是个方法类型,比如double(int),有一个参数,类型是int,返回值类型是double. std::packag

c/c++ 多线程 等待一次性事件 std::promise用法

多线程 等待一次性事件 std::promise用法 背景:不是很明白,不知道为了解决什么业务场景,感觉std::async可以优雅的搞定一切的一次等待性事件,为什么还有个std::promise. 用法:和std::async一样,也能够返回std::future,通过调用get_future方法.也可以通过future得到线程的返回值. 特点: 1,是个模板类,模板类型是个方法类型,比如double(int),有一个参数,类型是int,返回值类型是double. std::promise<i

[C++11 并发编程] 13 使用期望等待一次性事件

C++标准库使用期望(future)来支持一次性事件的等待.要等待某种一次性事件的线程可以获取一个代表该该事件的期望.这个线程可以每隔一段事件周期性的查询这个期望.此外,这个线程也可以继续做其它的处理,直到需要等待这个一次性事件才被挂起.通过期望还可以可以传递数据. C++标准库提供了两种期望unique future(std::future<>)和shared futures(std::shared_future<>),都声明在<future>库头文件中.std::f

同步并发操作之等待一次性事件

有时候需要用一些后台线程来完成计算,这些计算往往都是一次性的,线程计算完后便结束.这时候可以使用条件变量,但是有点浪费,我们只需要获取一次结果.C++标准库中有头文件<future>,很形象"未来",获取未来计算的结果. 使用std::async来启动一个异步任务.用std::future对象来存储异步任务返回的结果,这个对象存储结果.当我们需要结果时,只需调用get()方法.这时如果还没计算完毕,当前线程会阻塞. #include<future> #inclu

c/c++ 多线程 多个线程等待同一个线程的一次性事件

多线程 多个线程等待一个线程的一次性事件 背景:从多个线程访问同一个std::future,也就是多个线程都在等待同一个线程的结果,这时怎么处理. 办法:由于std::future只能被调用一次get方法,也就是只能被某一个线程等待(同步)一次,不支持被多个线程等待.所以std::sharted_future,就应运而生了. 特点:std::sharted_future可以被复制,std::future是不可以的被复制的. std::sharted_future的3种创建方式(fut为std::

python3 中 Event.wait 多线程等待

python3 中 Event.wait 多线程等待 event.wait(time) 等待 time 时间后,执行下一步.或者在调用 event.set() 后立即执行下一步. event.clear()  清除信号 event.set() 设置信号 event.isSet() 判断是否设置信号 要求: 定义一个按钮,等待 3秒钟,如果 3秒钟没有再次被点击,则执行下一步.否则,重新等待 3秒. 定义执行函数 1 2 3 4 5 6 7 def demo():   event.set()   

多线程编程与事件

时间片的概念大家应该都了解过,windows为每个进程分配时间片,当一个程序的时间片结束时,就会轮到下一个程序执行,当轮流速度比较快的时候,就好像多个进程同时执行一样,这就是windows多任务的方式,本次介绍的多线程其实跟这个很像,只不过线程是在进程内又划分的更小的可执行单位,windows为每个线程分配时间片,当轮到某个进程的某个线程执行的时候,该线程才开始执行,就好像是进程间的多任务一样,线程依赖于进程,进程结束则线程必定结束,线程结束则进程不一定结束,线程就是一个进程中的某个可执行的模块

多线程等待唤醒机制之生产消费者模式

上篇楼主说明了多线程中死锁产生的原因并抛出问题--死锁的解放方案,那么在本篇文章,楼主将引用一个KFC生产汉堡,顾客购买汉堡的过程来说明死锁解决方案及多线程的等待唤醒机制. 简单地用一幅图来说明KFC生产汉堡,顾客来消费的过程: 场景分析: 资源类:Hamburger 设置汉堡数据:SetThread(生产者) 获取汉堡数据:GetThread(消费者) 测试类:HamburgerTest 不同种类的线程(生产者.消费者)针对同一资源(汉堡)的操作 当汉堡有存货的时候,汉堡师傅不再生产,顾客可消

QT多线程及通过事件进行通信(通过自定义事件,然后QApplication::postEvent给主界面,我之前用的是信号槽)

可以通过QThread实现跨平台的多线程开发,Qt库负责在特定平台上的特定多线程实现.要采用QThread进行多线程开发,首先需要包含头文件: #include <QThread> 然后需要从QThread继承一个自己的线程类,暂作MyThread,关键是要实现QThread内的一个虚函数run.在run函数内部,最后一般都调用exec(),使得线程进入事件循环,否则线程主函数run运行结束,线程也就退出了. class MyThread : public QThread { public: