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

  

boost asio 学习(五) 错误处理的更多相关文章

  1. boost asio 学习(一)io_service的基础

    原文  http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio/ 编译环境 b ...

  2. boost asio 学习(六) 定时器

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=7 6 定时器 ...

  3. boost asio 学习(九) boost::asio 网络封装

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...

  4. boost asio 学习(八) 网络基础 二进制写发送和接收

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=9 8. Net ...

  5. boost asio 学习(七) 网络基础 连接器和接收器(TCP示例)

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=8 7. Net ...

  6. boost asio 学习(二)了解boost::bind

    2.了解boost::bind使用boost::bind封装一个函数,考虑以下例子示例2a #include <iostream> #include <boost/bind.hpp& ...

  7. BOOST ASIO 学习专贴

    本文已于20170903更新完毕,所有boost asio 代码均为本人手抄.编译器为vs2013,并且所有代码已经上传,本文下方可下载源码 为了学习boost asio库,我是从boost的官方bo ...

  8. boost::asio 学习

    安装 下载-解压 指定安装目录 ./bootstrap.sh --prefix=/usr/local/boost_1_68_0 查看所有必须要编译才能使用的库 ./b2 --show-librarie ...

  9. boost asio 学习(四)使用strand将任务排序

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=5 4. Seri ...

随机推荐

  1. 【Python】2.x与3​​.x版本的选用&版本间的区别

    转自 http://www.runoob.com/python/python-2x-3x.html 一.2.x与3​​.x版本的选用建议 Python的3​​.0版本,常被称为Python 3000, ...

  2. 理解OpenShift(2):网络之 DNS(域名服务)

    理解OpenShift(1):网络之 Router 和 Route 理解OpenShift(2):网络之 DNS(域名服务) 理解OpenShift(3):网络之 SDN 理解OpenShift(4) ...

  3. Pymysql部分

    安装: 1 执行SQL import pymysql # 创建连接 conn = pymysql.connect(host='172.30.2.233', port=3306, user='root' ...

  4. [UE4]Image

    一.Image.Appearance.Brush.Tiling:平铺方式 1.No Tile:不平铺,拉伸会变形 2.Horizontal:横向平铺.纵向拉伸会变形 3.Vertical:纵向平铺.横 ...

  5. 支付宝 net

  6. 第17课 类型萃取(1)_基本的type_traits

    1. type_traits类型萃取 (1)type_traits通过定义一些结构体或类,并利用模板类特化和偏特化的能力,给类型赋予一些特性,这些特性根据类型的不同而异.在程序设计中可以使用这些tra ...

  7. Resilience4j usage

    1. pom 1) normal <dependency> <groupId>io.github.resilience4j</groupId> <artifa ...

  8. html 设置input框的记忆功能(联想内容)

    autocomplete=“on/off” 1.默认情况下,autocomplete的值是on.你可以将其设置为off. 2.autocomplete属性可以放在input 元素上,也可以放在form ...

  9. Java并发编程75个问答

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  10. C程序设计第一次实验报告

    C程序设计实验报告 实验项目: 1.字符与ASCII码 2.运算符与表达式的运用 3.顺序结构应用程序 4.数学函数的算法描述 5.鸡兔同笼的算法描述 6.确定坐标的运算描述 姓名:王煜 实验地点:教 ...