使用Boost ASIO进行Boost异常处理

Mis*_*tyD 2 c++ boost boost-asio

我打算在这个例子5A -它涵盖了异常,并提升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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么这里没有捕获到异常?为什么作者必须同时进行力学模拟error codetry-catch捕捉这样的异常

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

我也听不懂作者的意思

为了再次澄清我们是否将io_service用于用户工作,如果工作可以生成异常,则必须使用异常处理。如果我们仅将io_service用于boost :: asio函数,则可以使用异常处理或error变量,无论哪种方式都可以。如果我们将io_service用于boost :: asio函数和用户工作,则可以使用这两种方法,也可以仅使用异常处理方法,但如果工作可以生成异常,则不仅可以使用错误变量。这应该很容易理解。

如果有人可以澄清这一点,我将不胜感激

Igo*_* R. 5

您引用的解释有些误导。

实际上,它会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);
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

因此,最重要的是使用抛出重载就足够了(并且可以选择使用多个catch处理程序来区分异常类型)。