当前位置: 技术问答>linux和unix
Linux下,Boost.Asio是如何通过epoll做到IO异步的
来源: 互联网 发布时间:2017-05-16
本文导语: 背景:epoll的实现是基于回调的,如果fd有期望的事件发生就通过回调函数将其加入epoll就绪队列中,用户针对该队列中的文件句柄发起相应操作,如read等,此时数据真正才会开始从内核buffer写入应用buffer中,整个过程是一种同...
背景:epoll的实现是基于回调的,如果fd有期望的事件发生就通过回调函数将其加入epoll就绪队列中,用户针对该队列中的文件句柄发起相应操作,如read等,此时数据真正才会开始从内核buffer写入应用buffer中,整个过程是一种同步IO。而Boost.Asio采用Proactor模式实现了异步IO,也就是说用户在发起async_read后,可以去进行其它操作,内核将数据从内核buffer写入应用buffer,最后会通知其数据已经拷贝完毕。
问题:Boost.Asio在Linux下封装epoll这种同步接口是如何做到异步IO的。看了源代码,有async_read,但没有看出其中的奥妙,请指点,谢谢
问题:Boost.Asio在Linux下封装epoll这种同步接口是如何做到异步IO的。看了源代码,有async_read,但没有看出其中的奥妙,请指点,谢谢
|
看io_service类里的成员impl_, 贴几段代码你应该就明白了,
detail/impl/epoll_reactor.ipp 里有很多epoll的封装
// io_service.hpp
typedef class task_io_service io_service_impl;
...
class io_service: private noncopyable
{
private:
typedef detail::io_service_impl impl_type;
...
impl_type& impl_;
};
// detail/task_io_service.hpp
#include
...
class task_io_service
: public boost::asio::detail::service_base
{
...
reactor* task_;
...
};
// detail/reactor_fwd.hpp
typedef class epoll_reactor reactor;
// detail/epoll_reactor.hpp
class epoll_reactor
: public boost::asio::detail::service_base
{
...
private:
...
BOOST_ASIO_DECL static int do_epoll_create();
...
};
// detail/impl/epoll_reactor.ipp
int epoll_reactor::do_epoll_create()
{
...
if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
{
fd = epoll_create(epoll_size);
if (fd != -1)
::fcntl(fd, F_SETFD, FD_CLOEXEC);
}
...
return fd;
}
detail/impl/epoll_reactor.ipp 里有很多epoll的封装