IO设计模式之Reactor和Proactor

Posted 我是攻城师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO设计模式之Reactor和Proactor相关的知识,希望对你有一定的参考价值。

前言

上面文章中,我们提到不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成,所以就演变出来两种高性能的io的设计模式,分别是Reactor(同步IO)和Proactor(异步IO)。

关于Reactor

Reactor英文意思为反应器,类似于核能的反应堆一样,所有的能量都源源不断从这里传出.或者更贴切一点叫事件的分发器。在Reactor中,事件分离器负责等待文件描述符或socket为读写操作准备就绪,然后将就绪事件传递给对应的处理器,最后由处理器负责完成实际的读写工作。

Linux epoll 使用 Reactor 模式。Reactor 模式使用同步 I/O(一般来说)。Reactor 的标准(典型)的工作方式是:

(1)应用程序注册读就绪事件和相关联的事件处理器

(2)Reactor阻塞等待内核事件通知

(3)Reactor收到通知,然后分发可读写事件(读写准备就绪)到用户事件处理函数

(4)用户读取数据,并处理数据

(5)事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返还控制权。

这里面需要注意,事件分离器仅仅发现当有io事件都写就绪的时候,会通知用户线程来读取数据,这一步相当于io阻塞的第二个阶段,从内核空间拷贝数据到用户空间是由用户线程完成的,所以Reactor模式实际上还属于同步IO的模式,当然为了架构更灵活和性能更好,一般情况下事件分离器和实际的处理器线程是分开的,类似Netty里面的boss线程组合worker线程组一样。

关于Proactor

Proactor英文意思前摄器,是一种异步的IO设计模式。这种模式更加理想,但真正支持纯异步的io模式,目前只有windows的Windows IO completion port.(iocp)模型。

Windows iocp 使用 Praactor 模式。Praactor 模式使用异步 I/O(一般来说)。Praactor 的标准(典型)的工作方式是:

(1)应用程序初始化一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读取就绪事件,而是关注读取完成事件,这是区别于Reactor的关键。

(2)事件分离器等待读取操作完成事件

(3)在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作,并将读取的内容放入用户传递过来的缓存区中。这也是区别于Reactor的一点,Proactor中,应用程序需要传递缓存区。

(4)事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓存区读取数据,而不需要进行实际的读取操作。

从上面的描述中能够看到,Proactor模式中,操作系统相当于直接把IO操作的两阶段工作都给干了,这也要求应用程序在注册异步任务时,需要传递一个缓存区,用来存放结果数据。这里面事件分离器关注的是io的完成事件,而不是就绪时间,当分离器通知应用程序时,应用程序可以直接就能处理数据了。

总结

Reactor和Proactor是两种高性能的IO设计模式,分别用于同步IO和异步IO的策略,可以看出它们都是采用的IO复用的模式,都是对某个IO事件的事件通知(即告诉某个模块,这个IO操作可以进行或已经完成)。在结构上,两者也有相同点:demultiplexor负责提交IO操作(异步)、查询设备是否可操作(同步),然后当条件满足时,就回调handler;

不同点在于,异步情况下(Proactor),当回调handler时,表示IO操作已经完成(数据已从系统内核拷贝到程序内存);同步情况下(Reactor),回调handler时,表示IO设备可以进行某个操作(can read or can write,数据准备就绪,但是用户需要自己将数据从系统内核拷贝到程序内存)。

你可能还对下面的文章感兴趣:





以上是关于IO设计模式之Reactor和Proactor的主要内容,如果未能解决你的问题,请参考以下文章

面试官:什么是 Reactor 和 Proactor

转帖两种IO模式:Proactor与Reactor模式

Reactor和Proactor模式的讲解(关于异步,同步,阻塞与非阻塞)

高性能 I/O 设计模式之Reactor

Reactor 和 Proactor 模式

Reactor 和 Proactor 模式