c/c++ 多线程 等待一次性事件 异常处理
程序员文章站
2022-04-09 18:15:53
多线程 等待一次性事件 异常处理 背景:假设某个future在等待另一个线程结束,但是在被future等待的线程里发生了异常(throw一个异常A),这时怎么处理。 结果:假设发生了上面的场景,则在调用future的get方法时,就会得到被future等待的线程抛出的异常A。 3种情况: 1,std ......
多线程 等待一次性事件 异常处理
背景:假设某个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; } }