25. 子线程使用poll处理连接IO事件

90 阅读2分钟

上一讲引入了 reactor 反应堆模式,并让 reactor 反应堆同时分发 Acceptor 上的连接建立事件和已建立连接的 I/O 事件。

这种模式在发起连接请求的客户端非常多的情况下,有一个地方是有问题的,那就是单 reactor 线程既分发连接建立,又分发已建立连接的 I/O,有点忙不过来,在实战中的表现可能就是客户端连接成功率偏低。

再者,新的硬件技术不断发展,多核多路 CPU 已经得到极大的应用,单 reactor 反应堆模式看着大把的 CPU 资源却不用,有点可惜。

这一讲我们就将 acceptor 上的连接建立事件和已建立连接的 I/O 事件分离,形成所谓的主 - 从 reactor 模式。

主 - 从 reactor 模式

主 - 从这个模式的核心思想是,主反应堆线程只负责分发 Acceptor 连接建立,已连接套接字上的 I/O 事件交给 sub-reactor 负责分发。其中 sub-reactor 的数量,可以根据 CPU 的核数来灵活设置。

比如一个四核 CPU,我们可以设置 sub-reactor 为 4。相当于有 4 个身手不凡的反应堆线程同时在工作,这大大增强了 I/O 分发处理的效率。而且,同一个套接字事件分发只会出现在一个反应堆线程中,这会大大减少并发处理的锁开销。

image.png

主反应堆线程一直在感知连接建立的事件,如果有连接成功建立,主反应堆线程通过 accept 方法获取已连接套接字,接下来会按照一定的算法选取一个从反应堆线程,并把已连接套接字加入到选择好的从反应堆线程中。

主反应堆线程唯一的工作,就是调用 accept 获取已连接套接字,以及将已连接套接字加入到从反应堆线程中。有个小问题,主从反应堆线程是两个不同的线程,如何把已连接套接字加入到另一个线程中呢?此时从反应堆线程或许处于事件分发的无限循环之中,在这种情况下应该怎么办呢?以后再说

主 - 从 reactor+worker threads 模式

如果说主 - 从 reactor 模式解决了 I/O 分发的高效率问题,那么 work threads 就解决了业务逻辑和 I/O 分发之间的耦合问题。把这两个策略组装在一起,就是实战中普遍采用的模式。