您的位置:首页 > 其它

boost asio 学习总结之 io_service

2011-03-30 22:30 429 查看
boost 版本 1_45_0

io_service 为异步I/O对像提供核心功能.以下是我们常用对象:

boost::asio::ip::tcp::socket
boost::asio::ip::tcp::acceptor
boost::asio::ip::udp::socket

这些对象的构造函数里都有一个必须的参数就是io_service&,
也就是说每个异步对像都需要1个io_service.但可以共用一个公共的io_service

io_service 为它们服务的过程,主要通过以下几个函数:
run;
run_one;
poll;
poll_one;
这几个函数都有几个重载,主要功能都一样.用户在自己创建的线程中调用这些函数,驱动异步操作完成.
这些函数的源代码在detail/impl下的io_service.ipp里.

io_service中有一个核心成员:
class io_service : private noncopyable
{
...
impl_type& impl_;
}
这个impl_ 是io_service类真正的实现,当使用者在调用io_service的成员函数时,大部分函数都会转而调用
impl_的相应同名函数.其中就包括上面4个重要的函数. ( 其实是一种实现和声明分开的一种方法,
好处是可以减少头文件的依赖性,
在detail/impl下的io_service.ipp里查看源代码)
impl_到底是什么东东:
impl_type -> typedef detail::io_service_impl impl_type;

而detail::io_service_impl 如果定义了BOOST_ASIO_HAS_IOCP 是:
detail::io_service_impl -> typedef win_iocp_io_service io_service_impl;
否则
detail::io_service_impl -> typedef task_io_service io_service_impl;

win_iocp_io_service 代表了具备完成端口功能的异步I/O.
task_io_service 则代表了另外一种异步I/O,可能是linux 下的epoll.这个不太了解,总之我们只需要知道这个I/O也是非常高效的就行.

它们的具体代码在detail文件夹内,先看下win_iocp_io_service有些啥:
一样有上面4个函数加一个init.
BOOST_ASIO_DECL void init (size_t concurrency_hint);

BOOST_ASIO_DECL size_t run (boost::system::error_code& ec);
BOOST_ASIO_DECL size_t run_one (boost::system::error_code& ec);
BOOST_ASIO_DECL size_t poll (boost::system::error_code& ec);
BOOST_ASIO_DECL size_t poll_one(boost::system::error_code& ec);
要看这些函数的源代码,就得去detail/impl下去找了. 找到win_iocp_io_service.ipp
win_iocp_io_service实现完成端口的具体过程:

1.io_service 的构造函数调用 win_iocp_io_service::init(),这个过程创建一个完成端口句柄.
2.用户创建若干线程,在线程函数里调用io_service::run,...,它们都会最终调用win_iocp_io_service::do_one();
3.do_one里会做一次完成端口状态查询并处理的工作.

run 一直重复调用do_one,完成I/O操作.
run_one 调用一次do_one,你需要自己做个循环来做重复动作.
另外两个同理.

在实际使用当中,发现有io_service_pool这种用法.创建N个io_service,然后各自run,而socket则看情况使用不同的io_service
个人感觉这种用法并不能提升性能,反而会降低性能.因为就完成端口来说,一个完成端口句柄足以处理所有的socket的异步操作了.
这种用法在task_io_service中是否能提升性能不敢断言.

by 老洪@ 2011-3-30晚
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: