Reactor模式和Proactor模式

时间:2022-05-25 06:25:14

Reactor模式和Proactor模式

转载: http://www.cnblogs.com/dawen/archive/2011/05/18/2050358.html

同步I/O和异步I/O

同步I/O: 在同步文件IO方式中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。

异步I/O: 在异步文件IO方式中,线程发送一个IO请求到内核,然后该线程继续处理其他的事情,内核完成IO请求后,将会通知线程IO操作完成了。

Reactor模式和Proactor模式

1. 标准定义

一般地,I/O多路复用机制都依赖于一个事件多路分离器(Event Demultiplexer)。
分离器对象可以将来自事件源的I/O事件分离出来,并分发到对应的read/write事件处理器(Event Handler)。
开发人员预先注册需要处理的事件及其事件处理器(或回调函数);事件分离器负责将请求事件传递给事件处理器。

两个与事件分离器有关的模式是Reactor和Proactor。
Reactor模式采用同步IO,而Proactor采用异步IO。

  • 在Reactor模式中,事件分离器负责等待文件描述符或socket为读/写操作准备就绪,然后将就绪事件传递给对应的处理器,最后由处理器负责完成实际的读/写工作。

  • 在Proactor模式中,事件处理器负责发起异步读/写请求,然后去干别的事。I/O操作本身由操作系统来完成。
    传递给操作系统的参数需要包括用户定义的数据缓冲区地址和数据大小,操作系统才能从中读取操作所需数据,或写入请求所需的结果数据。
    当操作系统完成I/O操作,事件分离器捕获I/O操作完成事件,然后将事件传递给对应事件处理器。
    典型的异步模式实现,都建立在操作系统支持异步API的基础之上,我们将这种实现称为“系统级”异步或“真”异步,因为应用程序完全依赖操作系统执行真正的I/O工作。

2. 举例

在Reactor中处理read事件:

  • 注册read就绪事件和相应的事件处理器
  • 事件分离器等待read就绪事件
  • read就绪事件到来,激活分离器,分离器调用read就绪事件对应的处理器
  • 事件处理器完成实际的read操作,处理读到的数据,注册新的事件,然后返还控制权

在Proactor中处理read事件:

  • 事件处理器发起异步read操作(注意:操作系统必须支持异步IO)。在这种情况下,处理器无视I/O就绪事件,它关注的是完成事件,因此处理器可以去干别的事。
  • 事件分离器等待read操作完成事件
  • 在分离器等待过程中,操作系统利用并行的内核线程执行实际的read操作,并将结果数据存入用户自定义缓冲区,最后通知事件分离器read操作完成
  • 事件分离器通知申请read操作的事件处理器
  • 事件处理器处理用户自定义缓冲区中的数据,然后启动一个新的异步操作,并将控制权返回给事件分离器

3. 总结

相同点:

都是对某个IO事件的事件通知(即告诉某个模块,这个IO操作可以进行或已经完成)。

在结构上,两者也有相同点:demultiplexor负责提交IO操作(异步)、查询设备是否可操作(同步),然后当条件满足时,就回调handler。

不同点:

同步情况下(Reactor模式),回调handler时,表示I/O设备可以进行某个操作(can read or can write)。

异步情况下(Proactor模式),当回调handler时,表示IO操作已经完成,handler可以直接拿到结果数据,然后去处理。