1.Reactor和Proactor模式的比较
两种I/O多路复用模式:Reactor和Proactor。一般地,I/O多路复用机制都依赖于一个事件多路分离器(Event Demultiplexer)。分离器可将来自事件源的I/O事件分离出来,并分发到对应的read/write事件处理器(Event Handler)。开发人员需预先注册需要处理的事件及其事件处理器(或回调函数);事件分离器负责将请求事件传递给事件处理器。
两个与事件分离器有关的模式是Reactor和Proactor。Reactor模式采用同步IO,而Proactor采用异步IO。
在Reactor中,事件分离器负责等待文件描述符或socket为读写操作准备就绪,然后将就绪事件传递给对应的处理器,最后由处理器负责完成实际的读写工作。
而在Proactor模式中,处理器--或者兼任处理器的事件分离器,只负责发起异步读写操作。IO操作本身由操作系统来完成。传递给操作系统的参数需要包括用户定义的数据缓冲区地址和数据大小,操作系统才能从中得到写出操作所需数据,或写入从socket读到的数据。事件分离器捕获IO操作完成事件,然后将事件传递给对应处理器。
以上的差异确定了两者不同的应用场景。Reactor框架中用户定义的操作是在实际操作之前调用的。比如你定义了操作是要向一个SOCKET写数据,那么当该SOCKET可以接收数据的时候,你的操作就会被调用;而Proactor框架中用户定义的操作是在实际操作之后调用的。比如你定义了一个操作要显示从SOCKET中读入的数据,那么当读操作完成以后,你的操作才会被调用。
Proactor和Reactor都是并发编程中的设计模式,都是用于派发/分离IO操作事件的。这里所谓的IO事件也就是诸如read/write的IO操作。"派发/分离"就是将单独的IO事件通知到上层模块。两个模式不同的地方在于,Proactor用于异步IO,而Reactor用于同步IO。
2.Proactor模式详细介绍
proactor模式的整体结构图如下:
整体流程如下:
(1)为了异步式的执行服务,作为客户端的应用程序将异步操作传递给异步操作处理器以完成初始化操作。同时,客户端需向异步操作处理器指明异步操作完成后回调哪个完成句柄执行后续的工作。(注册回调函数)
(2)客户端在异步操作处理器激活操作之后,操作和客户端可以和其他应用程序激活的异步操作一起并行的运行。
(3)当操作执行完后,异步操作处理器取回操作初始化时客户端限定的完成句柄和proactor。然后异步操作处理器传递异步操作的结果和完成句柄给proactor,由其完成分发。
(4)proactor分发完成句柄的钩子方法,并传递完成数据。
详细的处理过程如下: