Reactor和Proactor对比
常见的IO事件处理模型有两种:Reactor和Proactor。Redis中的ae就是采用的Reactor事件处理模型,Proactor需要操作系统的支持,目前暂时还没接触到相关的使用场景,主要是学习模型结构。
Reactor模型
- Handler:用来标识一个文件描述符
- Synchronous Event Demultiplexer:同步事件多路分解器,由select、poll或者epoll函数来实现,调用后会阻塞,直到等待Handler上的一个或多个事件发生
- Event Handler:事件处理接口
- Concrete Event Handler:事件处理接口的实现类,用来实现应用程序所提供的特定事件处理逻辑
- Reactor:Reactor反应堆,主要实现以下功能:
1)注册和删除关注的文件描述符
2)运行事件循环
3)有就绪事件到来时,分发事件到之前注册的回调函数上处理
Reactor时序图
- 运行主程序,将关注的事件handler注册到Reactor中
- 主程序调用Reactor,进入无限事件循环,等待注册的事件到来
- 当事件到来时,调用select返回待处理的事件,Reactor将事件分发到之前注册的回调函数中去处理
Proactor模型
- Handler:用来标识一个文件描述符;
- Asynchronous Operation Processor:异步操作处理器,负责执行异步操作(一般由操作系统内核实现)
- Asynchronous Operation:异步操作
- Completion Event Queue:完成事件队列,将异步操作完成的结果放到队列中
- Proactor:主动器,从完成事件队列中取出结果,分发调用相应的后续处理逻辑
- Completion Handler:完成事件接口
- Concrete Completion Handler:完成事件接口的实现类,用来实现应用程序所提供的特定事件处理逻辑
Proactor时序图
- 应用程序(Initiator)调用异步操作处理器(Asynchronous Operation Processor)提供的异步操作接口函数,调用之后应用程序和异步操作处理就独立运行
- 应用程序(Initiator)调用主动器(Proactor),进行无限的事件循环,监听完成事件队列(Completion Event Queue)中的事件,等待完成事件到来
- 异步操作处理器(Asynchronous Operation Processor)执行异步操作,完成后将结果放入到完成事件队列(Completion Event Queue);
- 主动器(Proactor)从完成事件队列(Completion Event Queue)中取出结果,分发到相应的完成事件(Concrete Completion Handler)回调函数处理逻辑中
对比
- Reactor是被动的,先将文件描述符注册到事件处理上,被动等待select返回就绪的文件描述符以后再处理后续的读写IO操作。Proactor是主动的,调用异步后立刻返回,由内核负责读写IO操作,处理完以后调用相应的完成事件回调函数处理后续逻辑
- Reactor是同步IO,Proactor是异步IO
- Reactor实现相对简单;Proactor实现复杂
- Reactor处理耗时长的操作会造成事件分发的阻塞,影响到后续事件的处理;Proactor异步接收能够处理多个耗时长的并发场景
- Reactor模型中用户定义的操作是在实际操作之前调用的(比如:定义了操作要向某个socket写数据,那么当该socket可以接收数据的时候,你的操作就会被调用);Proactor模型中用户定义的操作是在实际操作之后调用的(比如:定义了一个操作要向某个socket写数据,那么当操作系统把数据写入socket完成以后,你的操作才会被调用)。