提升异常和线程安全性 - 优于常规异常处理

问题描述:

我遇到了this文章,它声明(复制 - 为了方便粘贴)。我不明白它,以及它如何更有利于通常的异常处理。在do_work代码中,error实例作为对新创建线程的引用传递。现在,如果出现错误,则会重新排列。那之后发生了什么?以下方法做什么?提升异常和线程安全性 - 优于常规异常处理

error = boost::exception_ptr(); 
error = boost::current_exception(); 

这是从链路

使用boost异常的另一好处是线程安全 能力。它允许在线程 之间进行例外处理而没有问题。

例如这个函数抛出一个克隆就绪例外:

void do_work() 
{ 
    boost::exception_ptr error; 
    boost::thread t(boost::bind(worker_thread,boost::ref(error))); 
    t.join(); 
    if(error) 
     boost::rethrow_exception(error); 
} 

可能被截获并克隆到由其他线程 进行安全,例如:

#include <boost/exception_ptr.hpp> 
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 

void do_work(); //throws cloning-enabled boost::exceptions 

void worker_thread(boost::exception_ptr & error) 
{ 
    try 
    { 
     do_work(); 
     error = boost::exception_ptr(); 
    } 
    catch(...) 
    { 
     error = boost::current_exception(); 
    } 
} 

boost::exception_ptr()将默认构造一个类似于空指针的异常指针,这意味着在if-check中它将评估为false,表示没有错误。
boost::current_exception()返回指向catch子句中当前活动异常的异常指针。它基本上捕获异常,以便您可以在if检查中重新抛出异常。

作为避免所有这些样板代码的替代方案,我建议使用std::async/boost::async,它提供了所有开箱即用的功能。

我不确定“正常”异常处理是什么意思,但是这可以让你处理调用端的错误,表明你的线程没有完成它应该做的工作。