1. Reactor
Reactor(反应器)的设计是一种事件驱动思想,比如Java NIO中,socket
过来时有四种事件:
- connectable
- acceptable
- readable
- writable
我们为每一种事件都编写一个处理器,然后设置每个socket
要监听哪种情况,随后就可以调用对应的处理器。
image
图中的input
就可以当作socket
,中间的Service Hanlder&event dispatch
的作用就是监听每一个socket
(需要实现把socket
注册进来,并指定要监听哪种情况),然后给socket
派发不同的事件。
实际使用时的三种工作模型
单线程模型
image-
Reactor
:监听client,并且dispatch事件处理器 -
acceptor
:与client进行连接 -
handlers
:业务逻辑,比如收到消息->计算结果->返回消息
多线程模型
image在业务逻辑部分使用线程池,可以提高效率,但增加了代码复杂性(线程之间的数据共享)。
多Reactor多线程模型
image这种模型下将Reactor分为一个主Reactor,一个子Reactor,主Reactor负责进行监听,子Reactor负责dispatch事件。
2. Proactor
imageProactor与Reactor较为类似。
以读取数据为例:
Reactor模式
-
应用程序注册读就绪事件和相关联的事件处理器
-
事件分离器等待事件的发生
-
当发生读就绪事件的时候,事件分离器调用第一步注册的事件处理器
-
事件处理器首先执行实际的读取操作,然后根据读取到的内容进行进一步的处理
Proactor模式
-
应用程序调用一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读取就绪事件,而是关注读取完成事件,这是区别于Reactor的关键。
-
事件分离器等待读取操作完成事件
-
在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作(异步IO都是操作系统负责将数据读写到应用传递进来的缓冲区供应用程序操作,操作系统扮演了重要角色),并将读取的内容放入用户传递过来的缓存区中。这也是区别于Reactor的一点,Proactor中,应用程序需要传递缓存区。
-
事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓存区读取数据,而不需要进行实际的读取操作。
区别
Reactor中,监听是否有可读或可写事件,然后读/写操作是由程序进行的。而Proactor中,直接监听读/写操作是否完成,也就是说读/写操作是否OS来完成,并将读写数据放入一个缓冲区提供给程序。
网友评论