【问题标题】:Boost Exception Handling with Boost ASIO使用 Boost ASIO 提升异常处理
【发布时间】:2014-12-03 07:08:41
【问题描述】:

我正在查看 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;
}

我的问题是为什么这里没有捕获异常?为什么作者必须同时使用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 功能和用户工作,那么我们可以使用这两种方法或只使用 异常处理方法,但不仅是错误变量,如果 工作可以产生异常。这应该很简单 跟随。

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

【问题讨论】:

    标签: c++ boost boost-asio


    【解决方案1】:

    您引用的解释有些误导。

    实际上,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 &amp;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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      • 2015-08-07
      • 2023-03-21
      相关资源
      最近更新 更多