http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=6
5. Error handling
接下来我们需要注意的话题是错误处理。换句话说就是函数抛出异常时发生了什么
Boost::asio 给予用户两种选择来处理。错误通过handler传播,指出线程呼叫run或者poll系列函数的位置。用户可以能处理通过异常抛出的状态或者是接收返回的错误变量。更多关于BOOST的信息,可以参考boost 的错误与异常处理。
首先我们看看异常处理错误的方法
#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream> boost::mutex global_stream_lock; void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl; global_stream_lock.unlock(); try { io_service->run(); } catch( std::exception & ex ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Exception: " << ex.what() << std::endl; global_stream_lock.unlock(); } global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl; global_stream_lock.unlock(); } void RaiseAnException( boost::shared_ptr< boost::asio::io_service > io_service ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] " << __FUNCTION__ << std::endl; global_stream_lock.unlock(); 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 ) ); global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] The program will exit when all work has finished." << std::endl; global_stream_lock.unlock(); 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函数释放,work线程因此退出。所有线程退出后,程序由于join_all的返回而结束。
下面看看使用错误变量返回异常的例子
#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream> boost::mutex global_stream_lock; void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl; global_stream_lock.unlock(); boost::system::error_code ec; io_service->run( ec ); if( ec ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Exception: " << ec << std::endl; global_stream_lock.unlock(); } global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl; global_stream_lock.unlock(); } void RaiseAnException( boost::shared_ptr< boost::asio::io_service > io_service ) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] " << __FUNCTION__ << std::endl; global_stream_lock.unlock(); 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 ) ); global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] The program will exit when all work has finished." << std::endl; global_stream_lock.unlock(); 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; }
上面这个代码将引起程序崩溃。通过调试,我们可以发现抛出的异常没有被处理
正确处理如下
#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream> boost::mutex global_stream_lock; void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl; global_stream_lock.unlock(); while (true) { try { boost::system::error_code ec; io_service->run(ec); if (ec) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Error: " << ec << std::endl; global_stream_lock.unlock(); } break; } catch (std::exception & ex) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Exception: " << ex.what() << std::endl; global_stream_lock.unlock(); } } global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl; global_stream_lock.unlock(); } void RaiseAnException(boost::shared_ptr< boost::asio::io_service > io_service) { global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] " << __FUNCTION__ << std::endl; global_stream_lock.unlock(); 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) ); global_stream_lock.lock(); std::cout << "[" << boost::this_thread::get_id() << "] The program will exit when all work has finished." << std::endl; global_stream_lock.unlock(); 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; }
时间: 2024-10-12 08:57:36