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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM