我正在查看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 code
和try-catch
捕获这样的异常
try
{
boost::system::error_code ec;
io_service->run( ec );
if( ec )
{
....
}
break;
}
catch( std::exception & ex )
{
....
}
我也不明白作者说的是什么意思
To further clarify once again if we are using the io_service for user work, we have to use exception handling if the work can generate exceptions. If we are using the io_service for boost::asio functions only, then we can use exception handling or the error variable as either will do. If we are using the io_service for both boost::asio functions and user work, then we can either use both methods or just the exception handling method, but not only the error variable if the work can generate an exception. That should be pretty straightforward to follow.
如果有人能澄清这一点,我将不胜感激
最佳答案
您引用的解释有些误导。
实际上,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;
}
因此,底线是使用抛出重载就足够了(并且可以选择使用多个 catch
处理程序来区分异常类型)。
关于c++ - 使用 Boost ASIO 进行 Boost 异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27265674/