网络编程基础-Reactor线程模型-原理剖析

1、Reactor基本概念

Reactor线程模型其实是一种设计模式,其核心思想就是将输入多路复用事件派发相结合,从而减少系统中活跃线程的数量。

像我们之前讲到的文章网络编程基础-IO模型深入理解_网络io-CSDN博客提到了其中网络IO模型(BIO、NIO、AIO),那这两者之间有什么关系呢?

①、Reactor模式通常建立在I/O复用的基础上。使用如epoll这样的机制可以让一个线程同时监控大量的socket连接,只有当某个socket上有数据可读/可写时才会被唤醒去处理,从而避免了传统的每个连接一个线程的开销。

②、为了配合Reactor模式下的高效处理流程,通常需要采用非阻塞I/O。这样即使某次读写操作未能立即完成,也不会导致线程阻塞,而是可以让出CPU时间片给其他任务。

③、Reactor线程模型充分利用了现代操作系统提供的高效I/O机制,特别是I/O复用和非阻塞I/O,来提高服务器程序对大规模并发连接的支持能力

所以要理解Reactor线程模型必须就要理解IO多路复用(Buffer、Channel、Selector)

2、Reactor中的三种角色

Acceptor

作用:专门用于处理新连接请求的事件处理器。

职责:通常与服务器端的监听套接字相关联,一旦监听到新的客户端连接请求,Acceptor就会被触发,它负责接受这个新连接,并创建一个新的SocketChannel(或其他形式的连接表示)。之后,Acceptor可以注册这个新连接到Reactor上,以便后续的数据读写事件能够得到处理。

这个可以理解为IO多路复用中与Channel相关的业务,其实就是Accept函数

Reactor

作用:作为事件循环的核心,负责监听多个I/O事件,并将这些事件分发给相应的处理器。

职责:管理一个或多个事件分发器(如epoll),监控一组文件描述符的状态变化。当有事件发生时,Reactor会根据事件类型调用对应的处理器。

这个可以理解为IO多路复用中的Selector

Handler

作用:处理具体业务逻辑的事件处理器。

职责:针对特定类型的事件执行操作,比如读取数据、写入响应等。每个Handler专注于一种类型的事件处理,它可以是读处理器、写处理器或者其他任何类型的处理器。

3、几种Reactor线程模型

1)、单Reactor-单线程模型

结构:

  • 一个Reactor线程负责监听连接请求,并处理所有客户端的I/O事件。
  • 所有的读写操作都在这个单一的线程中完成。

流程:

  • Reactor通过select或其他多路复用机制(epoll)监控多个客户端socket。
  • 当有新的连接请求时,Acceptor处理并接受连接。
  • 连接建立后,Reactor继续监听该连接上的读写事件。
  • 当读写事件发生时,相应的Handler处理这些事件,包括数据的读取、业务逻辑的执行以及结果的发送。

优点:模型简单,易于理解和实现。不涉及线程间的通信,避免了多线程编程中的复杂性。

缺点:所有的处理都依赖于一个线程,无法充分利用多核CPU。如果唯一的工作线程挂起或崩溃,整个系统将无法响应其他客户端。

2)、单Reactor-多线程模型

结构:

  • 一个Reactor线程负责监听和分发事件。
  • 多个工作线程(Worker线程池)负责处理具体的业务逻辑。

流程:

  • Reactor通过select监听客户端连接请求。
  • 新连接由Acceptor处理,并创建一个Handler来处理后续的读写事件。
  • 当读写事件发生时,Reactor将事件分发给对应的Handler。
  • Handler读取数据后,将数据处理任务提交给Worker线程池。
  • Worker线程处理完业务逻辑后,将结果返回给Handler,由Handler将结果发送回客户端。

优点:能够利用多核CPU提高性能。通过线程池分离I/O操作与业务逻辑处理,提高了系统的吞吐量。

缺点:Reactor线程仍然是单线程,高并发情况下可能成为性能瓶颈。线程间的数据共享和同步增加了复杂性。

3)、主从Reactor-多线程模型

结构:

  • 一个主Reactor(MainReactor)负责监听新连接请求。
  • 多个从Reactor(SubReactor)各自管理一部分已建立的连接,并处理这些连接上的读写事件。
  • 每个从Reactor通常有自己的工作线程池来处理具体的业务逻辑。

流程:

  • MainReactor通过select监听新的连接请求。
  • 当有新的连接请求时,Acceptor处理并接受连接,然后将新连接分配给某个SubReactor。
  • SubReactor将连接加入到自己的选择器中进行监听,并为该连接创建Handler。
  • 当连接上有读写事件发生时,SubReactor调用对应的Handler处理事件。
  • Handler读取数据后,将数据处理任务提交给对应的Worker线程池。
  • Worker线程处理完业务逻辑后,将结果返回给Handler,由Handler将结果发送回客户端。

优点:能够更好地扩展,适应更高并发的场景。分离了连接建立和I/O事件处理,使得系统更加灵活和高效。可以根据需要调整MainReactor和SubReactor的数量,以优化性能。

缺点:编程复杂度较高,需要仔细设计和协调各个组件。系统架构相对复杂,维护成本增加。

相关推荐
扶尔魔ocy2 天前
【Linux C/C++开发】epoll模式的开源库及原生socket实现
linux·网络编程·epoll
LL_break3 天前
线程3 JavaEE(阻塞队列,线程池)
java·开发语言·java-ee·线程·线程池·阻塞队列
deng-c-f4 天前
Linux C/C++ 学习日记(29):IO密集型与CPU密集型、CPU的调度与线程切换
linux·学习·线程·cpu·io密集·cpu密集
千里马学框架5 天前
安卓系统中线程优先级Priority查看方式汇总
android·framework·线程·安卓framework开发·优先级·priority
Qt程序员5 天前
基于原子操作的 C++ 高并发跳表实现
c++·线程·c/c++·原子操作·无锁编程
hellojackjiang20116 天前
全面适配iOS 26液态玻璃,基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布
ios·网络编程·即时通讯·im开发·rainbowchat
deng-c-f7 天前
Linux C/C++ 学习日记(28):KCP协议(四):如何实现更复杂的业务:将连接状态的管理进行封装,用户只需实现发送、接收、断开的处理逻辑。
学习·网络编程·kcp
deng-c-f8 天前
Linux C/C++ 学习日记(22):Reactor模式(二):实现简易的webserver(响应http请求)
linux·c语言·网络编程·reactor·http_server
deng-c-f9 天前
Linux C/C++ 学习日记(27):KCP协议(三):源码分析与使用示例
linux·服务器·网络·c++·网络编程·kcp
deng-c-f9 天前
Linux C/C++ 学习日记(26):KCP协议(二):kcp源码分享
c语言·c++·学习·网络编程·kcp