使用Boost ASIO增强异常处理

时间:2014-12-03 07:08:41

标签: c++ boost boost-asio

我正在讨论this示例5a - 它涵盖了使用boost asio进行异常处理 该示例的代码从该链接粘贴到此处以供快速参考

boost::mutex global_stream_lock;

void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service )
{
    ....

    try
    {
        io_service->run();
    }
    catch( std::exception & ex )
    {
        ....
    }

}

void RaiseAnException( boost::shared_ptr< boost::asio::io_service > io_service )
{
    io_service->post( boost::bind( &RaiseAnException, io_service ) );

    throw( std::runtime_error( "Oops!" ) );
}

int main( int argc, char * argv[] )
{
    boost::shared_ptr< boost::asio::io_service > io_service(
        new boost::asio::io_service
        );
    boost::shared_ptr< boost::asio::io_service::work > work(
        new boost::asio::io_service::work( *io_service )
        );


    boost::thread_group worker_threads;
    for( int x = 0; x < 2; ++x )
    {
        worker_threads.create_thread( boost::bind( &WorkerThread, io_service ) );
    }

    io_service->post( boost::bind( &RaiseAnException, io_service ) );

    worker_threads.join_all();

    return 0;
}

我的问题是为什么这里没有异常?为什么作者必须 mechansims error codetry-catch来捕捉这样的例外

try
        {
            boost::system::error_code ec;
            io_service->run( ec );
            if( ec )
            {
                ....
            }
            break;
        }
        catch( std::exception & ex )
        {
            ....
        } 

我也不明白作者的意思是说

  

如果我们正在为用户使用io_service,请再次澄清   如果工作可以生成,我们必须使用异常处理   例外。如果我们将io_service用于boost :: asio函数   只有,那么我们可以使用异常处理或错误变量作为   要么会做。如果我们将io_service用于boost :: asio   功能和用户工作,然后我们可以使用两种方法或只是   异常处理方法,但不仅是错误变量if   工作可以产生异常。这应该是非常简单的   跟随。

如果有人能澄清这个,我将不胜感激

1 个答案:

答案 0 :(得分:4)

你引用的解释有点误导。

实际上,io_service传播了从完成处理程序中逃脱的任何异常,因此无论我们是将它用于“用户工作”还是用于“asio函数”都无关紧要 - 在任何情况下我们都可能希望处理异常逃离io_service::run(不仅std::exception!)。 请考虑以下示例:

void my_handler(const error_code&)
{
  // this exception will escape from io_service::run()!
  throw 0;
}

void setup_timer()
{
  deadline_timer_.expires_from_now(seconds(5));
  deadline_timer_.async_wait(my_handler);
}

io_service::run(error_code &ec)io_service::run()之间的区别在于后者故意抛出异常,如果ec意味着错误。引自io_service.ipp

std::size_t io_service::run()
{
  boost::system::error_code ec;
  std::size_t s = impl_.run(ec);
  boost::asio::detail::throw_error(ec);
  return s;
}

所以,最重要的是,使用throw过载(以及可选的多个catch处理程序来区分异常类型)就足够了。