处理逻辑
Reactor 处理逻辑
在
- Synchronous Event Demultiplexer:同步事件分离器,用于监听各种事件,调用方调用监听方法的时候会被阻塞,直到有事件发生,才会返回。对于
Linux 来说,同步事件分离器指的就是IO 多路复用模型,比如epoll ,poll 等, 对于Java NIO 来说, 同步事件分离器对应的组件就是selector ,对应的阻塞方法就是select 。 - Handler:本质上是文件描述符,是一个抽象的概念,可以简单的理解为一个一个事件,该事件可以来自于外部,比如客户端连接事件,客户端的写事件等等,也可以是内部的事件,比如操作系统产生的定时器事件等等。
- Event Handler:事件处理器,本质上是回调方法,当有事件发生后,框架会根据
Handler 调用对应的回调方法,在大多数情况下,是虚函数,需要用户自己实现接口,实现具体的方法。 - Concrete Event Handler: 具体的事件处理器,是
Event Handler 的具体实现。 - Initiation Dispatcher:初始分发器,实际上就是
Reactor 角色,提供了一系列方法,对Event Handler 进行注册和移除;还会调用Synchronous Event Demultiplexer 监听各种事件;当有事件发生后,还要调用对应的Event Handler 。

- 我们注册
Concrete Event Handler 到Initiation Dispatcher 中。 Initiation Dispatcher 调用每个Event Handler 的get_handle 接口获取其绑定的Handle 。Initiation Dispatcher 调用handle_events 开始事件处理循环。在这里,Initiation Dispatcher 会将步骤2 获取的所有Handle 都收集起来,使用Synchronous Event Demultiplexer 来等待这些Handle 的事件发生。- 当某个
( 或某几个)Handle 的事件发生时,Synchronous Event Demultiplexer 通知Initiation Dispatcher 。 Initiation Dispatcher 根据发生事件的Handle 找出所对应的Handler 。Initiation Dispatcher 调用Handler 的handle_event 方法处理事件。
抽象来说,
- add:添加
socket 监听到reactor ,可以是listen socket 也可以使客户端socket ,也可以是管道、eventfd、信号等 - set:修改事件监听,可以设置监听的类型,如可读、可写。可读很好理解,对于
listen socket 就是有新客户端连接到来了需要accept 。对于客户端连接就是收到数据,需要recv 。可写事件比较难理解一些。一个SOCKET 是有缓存区的,如果要向客户端连接发送2M 的数据,一次性是发不出去的,操作系统默认TCP 缓存区只有256K 。一次性只能发256K ,缓存区满了之后send 就会返回EAGAIN 错误。这时候就要监听可写事件,在纯异步的编程中,必须去监听可写才能保证send 操作是完全非阻塞的。 - del:从
reactor 中移除,不再监听事件 - callback:就是事件发生后对应的处理逻辑,一般在
add/set 时制定。C 语言用函数指针实现,JS 可以用匿名函数,PHP 可以用匿名函数、对象方法数组、字符串函数名。

- Nginx:多进程
Reactor - Nginx+Lua:多进程
Reactor+ 协程 - Golang:单线程
Reactor+ 多线程协程 - Swoole:多线程
Reactor+ 多进程Worker
协程从底层技术角度看实际上还是异步