Reactor模式也称为反应器模式,是一种高性能的网络并发模式。
传统的多线程IO每接受一个连接就开一个线程来处理这个连接,由于线程个数有限,且频繁创建和销毁线程带来很大的开销,我们需要对其进行改进。
首先,最简单的reactor模式的思想是利用单线程来处理所有的连接,利用IO多路复用方式来同时监听多个连接,首先需要注册需要监听的描述符和它感兴趣的事件,然后在reactor上注册其相应的处理函数(即回调函数),在linux中利用epoll来循环读取是否发生感兴趣的事件,如果发生的话,就遍历其返回的描述符队列,依次执行其回调函数,当全部的事件都处理完毕之后,注意:在事件处理时候可能会向epoll中添加新的描述符,之后重新进入epoll_wait来判断是否发生感兴趣事件。
如果单线程reactor中有着许多的计算事件,在每一次的epoll_wait后都需要花费较多的时间计算,这样此时如果有新连接请求则不会接收,改进方式为使用工作者线程池,将计算过程放到ThreadPool中,但是注意:IO有关的工作还是放到reactor线程中执行,包括I/O的accept()、read()、write()和connect()。
此时已经可以用于一些小容量的应用场景了,但是对于有着高并发的场景依然不适合,这时候,我们进一步改进,得到了多Reactor线程模式,在该模型中reactor分为mainReactor和SubReactor,MainReactor只有一个,负责接受客户端连接,subReactor来完成已经连接的客户端和服务器的通信。当客户端向服务器端发出连接请求时候,mainReactor会经过epoll_wait后得知这个请求,在其回调函数中将新的连接加入到subReactor中,让subReactor负责该客户端和服务器端的通信。Reactor线程池中的每一Reactor线程都会有自己的Selector、线程和分发的事件循环逻辑。此时可以也添加工作者线程池,将非IO操作从subReactor线程中取出来交给工作者线程池来执行,这样能够提高subReactor线程的响应,不会因为一些耗时的业务而延迟对后面的IO请求的操作。