码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-08-31 23:41:36      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:c++   stdfuture   stdpromise   异常   并发   

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

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

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。

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

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

标签:c++   stdfuture   stdpromise   异常   并发   

原文地址:http://blog.csdn.net/yamingwu/article/details/48132297

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!