鸿 网 互 联 www.68idc.cn

当前位置 : 主页 > 编程语言开发 > 技术问答 > >

[C++11 并发编程] 16 在期望中保存异常

来源:互联网 作者:佚名 时间:2015-09-01 23:54
Java版本说明: Java开发中,经常遇到从GBK到Unicode码的转换;大家经常做的做法,大概有2种,一种是:native2ascii;只要保存好文件,每次编辑好文件,然后使

如果在异步线程中发生了异常,等待期望的线程如何才能知道并且正确的处理异常呢?

假设有如下所示的一个求平方根的函数:

double square_root(double x) { if(x<0) { throw std::out_of_range(“x<0”); } return sqrt(x); }

通常,如果在当前线程上下文中调用square_root(),方法如下:

double y=square_root(-1);在异步线程中调用square_root(),方法如下: std::future<double> f=std::async(square_root,-1); double y=f.get();理想情况下,两种方式都能通过y获得函数调用的执行结果。如果发生了异常,能让调用者知道这个异常,就更好了。

实际上,如果在std::async中执行的函数抛出了异常,这个异常将被存储在期望中,期望变为就绪状态,等待get()被挂起的线程将被唤醒,get()函数再次抛出这个存储在期望中的异常。

类似的,std::promise也有类似的功能,只不过需要我们显示的set_exception()接口来设置:

try { some_promise.set_value(calculate_value()); } catch(...) { some_promise.set_exception(std::current_exception()); }这里使用std::current_exception()来获取当前抛出的异常。除此之外,还可以使用std::copy_exception()直接产生一个新的异常存放到promise之中: some_promise.set_exception(std::copy_exception(std::logic_error("foo ")));在异常类型确定的情况下,,推荐使用这种方式,因为这样比起try/catch块不仅更加清晰,编译器在优化代码时,效果也更好。

到此为止,所有的示例代码都在使用std::future,但是std::future也有一定的限制,因为只有一个线程可以等待这个期望的返回。如果有多个线程需要等待同一个事件,我们需要使用std::shared_future。

版权声明:本文为博主原创文章,未经博主允许不得转载。

网友评论