前几天在看代码的时候上网上网找了关于异步proactor 执行流程的分析,在windows下面到有几篇不错的博文,但是在linux下面几乎没有很详细的介绍,现在看完了,写一下自己在看的过程中的疑惑和自己的分析,希望对大家学习有帮助。
在看asio之前先提几个问题:
1 异步的执行流程到底是怎样的?从用户发起操作到执行自己的完成回调函数,中间发生了什么?
2 proactor模式到底是怎么实现的呢?
3 都说run函数会在任务数为0的时候会退出循环,到底是怎么控制的?
4 run在多线程里执行的时候,到底是怎么随机分配任务的?
带着这几个问题,我们进入源码的世界,哈哈,此时边喝啤酒边写。首先先来看几个类型的定义,只有搞清楚每一个类型在linux下面到底是什么具体的类型,才好跟踪代码,下面以tcp 异步accept调用来进行分析:在应用层代码里最上层的类为
typedef basic_socket_acceptor
而basic_socket_acceptor 继承自 basic_io_object,在basic_io_object是一个模板类,传递给他的模板参数就是
socket_acceptor_service
typedef IoObjectService service_type;
typedef typename service_type::implementation_type implementation_type;
我们知道传递进来的IoObjectService即为 socket_acceptor_service ,那么implementation_type 是什么类型的呢?看代码继续分析,我们继续进入到socket_acceptor_service着各类, 这个类中的两个成员就能帮助我们找到我们想要的答案:
typedef detail::reactive_socket_service
typedef typename service_impl_type::implementation_type implementation_type;
原来service_type::implementation_type 就是 reactive_socket_service:: implementation_type, 那我们就继续看
reactive_socket_service吧(我们只分析linux下的,所以遇到宏定义影响定义的就直接说在linux下面的实现了),
struct implementation_type : reactive_socket_service_base::base_implementation_type 原来这里面的implementation_type是继承了基类的,那就继续看基类reactive_socket_service_base,这下子终于找到了implementation_type的最终定义:
struct base_implementation_type
{
socket_type socket_;
socket_ops::state_type state_;
reactor::per_descriptor_data reactor_data_;
};
大体说下这三个成员,socket_ 即为 要添加进epoll 里面的fd, state_表明是tcp 还是 udp, reactor_data_这个也依赖于具体的实现,这里就直说了,就是epoll_reactor,这个成员可以说是最重要的成员了,当fd 就绪时,通过这个成员进行所有的io操作和用户回调函数的回调,看下定义吧:
typedef class epoll_reactor reactor;从这里面就知道就是 epoll_reactor, 在看下epoll_reactor的 定义吧,
typedef descriptor_state* per_descriptor_data; 在 descriptor_state结构体里面就一个数据结构比较重要,那就是
op_queue
下来总结一下,不要嫌啰嗦:
在 basic_io_object 里面的 service_type 就是 socket_acceptor_service
implementation_type 就是 reactive_socket_service_base::base_implementation_type,
service_type& get_service()
{
return service;
}
返回的就是socket_acceptor_service,
implementation_type& get_implementation()
{
return implementation;
}
返回的就是reactive_socket_service_base::base_implementation_type。
把这两个结构体弄清楚之后,后面每一个异步调用就知道具体是调用那个类的具体实现。
后面继续看 operation这个神奇而有富有内涵的类。