我正在讨论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 code
和try-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 工作可以产生异常。这应该是非常简单的 跟随。
如果有人能澄清这个,我将不胜感激
答案 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
处理程序来区分异常类型)就足够了。