多線程 等待一次性事件 異常處理 背景:假設某個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;
}
}