• boost asio 学习(五) 错误处理


    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;
    }
    

      

  • 相关阅读:
    mybatis几种开发方式
    SpringData,JPA,MongoDB,Solr,Elasticsearch底层逻辑关系
    简论远程通信(RPC,Webservice,RMI,JMS的区别)
    spring/spring boot/spring mvc中用到的注解
    Centos常用命名
    Mybatis详解
    Java成长之路
    Hibernate 与Mybatis之比较
    Struts2 与SpringMVC之比较
    Maven 配置文件详解
  • 原文地址:https://www.cnblogs.com/itdef/p/5618158.html
Copyright © 2020-2023  润新知