网络编程基础-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的数量,以优化性能。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/902356.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

asp.net core 入口 验证token,但有的接口要跳过验证

asp.net core 入口 验证token,但有的接口要跳过验证 在ASP.NET Core中,你可以使用中间件来验证token,并为特定的接口创建一个属性来标记是否跳过验证。以下是一个简化的例子: 创建一个自定义属性来标记是否跳过验证: public clas…

基于PHP的http字段查询与注册(V1)(持续迭代)

目录 版本说明: 实现环境(WAMP): 数据库链接 查询页面 php处理逻辑 字段添加 版本说明: 该查询功能以查询http首部字段为目的实现的字段属性、字段内容的查询,以及对新字段信息的数据注册。 v1实现…

python 制作 发货单 (生成 html, pdf)

起因, 目的: 某个小店,想做个发货单。 过程: 先写一个 html 模板。准备数据, 一般是从数据库读取,也可以是 json 格式,或是 python 字典。总之,是数据内容。使用 jinja2 来渲染模板。最终的结果可以是 h…

多线程进阶——线程池的实现

什么是池化技术 池化技术是一种资源管理策略,它通过重复利用已存在的资源来减少资源的消耗,从而提高系统的性能和效率。在计算机编程中,池化技术通常用于管理线程、连接、数据库连接等资源。 我们会将可能使用的资源预先创建好,…

WPF+MVVM案例实战(七)- 系统初始化界面字体描边效果实现

文章目录 1、案例效果展示2、项目准备3、功能实现1、资源获取2、界面代码3、后台代码 4 源代码获取 1、案例效果展示 2、项目准备 打开项目 Wpf_Examples,新建系统初始化界面 WelcomeWindow.xmal,如下所示: 3、功能实现 1、资源获取 案例中使用的CSD…

Java | Leetcode Java题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution {public int longestPalindromeSubseq(String s) {int n s.length();int[][] dp new int[n][n];for (int i n - 1; i > 0; i--) {dp[i][i] 1;char c1 s.charAt(i);for (int j i 1; j < n; j) {char c2 s.char…

【Java并发编程】信号量Semaphore详解

一、简介 Semaphore&#xff08;信号量&#xff09;&#xff1a;是用来控制同时访问特定资源的线程数量&#xff0c;它通过协调各个线程&#xff0c;以保证合理的使用公共资源。 Semaphore 一般用于流量的控制&#xff0c;特别是公共资源有限的应用场景。例如数据库的连接&am…

Python | Leetcode Python题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)dp [[0] * n for _ in range(n)]for i in range(n - 1, -1, -1):dp[i][i] 1for j in range(i 1, n):if s[i] s[j]:dp[i][j] dp[i 1][j - 1] 2else:dp…

从病理AI的基础模型发展历程,看未来的医学AI发展趋势|个人观点·24-10-23

小罗碎碎念 在临床相关的人工智能&#xff08;AI&#xff09;模型发展方面&#xff0c;传统上需要大量标注数据集&#xff0c;这使得AI的进步主要围绕大型中心和私营企业展开。所以&#xff0c;在这期推文中&#xff0c;我会介绍一些已经商用的模型&#xff0c;并且为计划进军…

逻辑推理学习笔记

目的 立场辩护整理思绪 基本框架 论题 &#xff08;变化&#xff09; 我要证明&#xff08;讨论对象 变化&#xff09; 论据 &#xff08;变化&#xff09; 拿什么证明&#xff1f;也就是证据呈现。 论证 &#xff08;不变&#xff09; 要如何证明&#xff1f;逻辑框架…

通过conda install -c nvidia cuda=“11.3.0“ 安装低版本的cuda,但是却安装了高版本的12.4.0

问题 直接通过 conda install -c nvidia cuda"11.3.0"安装得到的却是高版本的 不清楚原理 解决方法 不过我们可以分个安装 runtime toolkit 和 nvcc 安装指定版本的 cudatoolkit 和 nvcc conda install -c nvidia cuda-cudart"11.3.58" conda instal…

【Linux系统编程】——Linux入门指南:从零开始掌握操作系统的核心(指令篇)

文章目录 查看 Linux 主机 ip以及登录主机Linux基础文件操作指令man&#xff1a;查看命令的手册页&#xff0c;了解命令的详细用法。pwd&#xff1a;显示当前目录路径。cd&#xff1a;切换目录。ls&#xff1a;列出当前目录下的文件和文件夹。mkdir&#xff1a;创建新目录。 文…

第三讲、C的运算符和表达式

一、运算符分类&#xff1a; &#xff08;1&#xff09;按运算对象的数目&#xff1a; 单目运算符 双目运算符 三目运算符 &#xff08;2&#xff09;按运算对象的数目&#xff1a; 算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、自增自减运算符、…

菜叶子芯酸笔记3:GPU、GPGPU、CUDA之间的关系;CUDA之外;Tensor Core

我今天看到B站一个up主很好的资料【云计算科普研究所的个人空间-云计算科普研究所个人主页-哔哩哔哩视频】&#xff0c;结合我这周的积累整理了这份我觉得相比之前逻辑更加完善的笔记。 先是GPU到GPGPU 到CUDA之间进化关系部分&#xff0c;然后CUDA之外的友商竞品部分&#xf…

orbslam安装

1.linux操作命令 pwd&#xff1a;查看终端所在路径 cd&#xff1a;切换路径 cd ..&#xff1a;跳回到上级目录 ls: 列出当前路径下的所有文件夹 touch&#xff1a;创建新的文件 mv &#xff1a;移动文件(在该文件所在目录的路径下执行此操作) 例如&#xff1a;mv test_file /ho…

vue3中mitt和pinia的区别和主要用途,是否有可重合的部分?

在 Vue 中&#xff0c;Mitt 和 Pinia 是两个不同的工具&#xff0c;它们的主要用途和功能有所不同&#xff0c;但在某些方面也存在重合的部分。 区别 Mitt&#xff1a; Mitt 是一个简单而强大的事件总线库&#xff0c;用于在组件之间进行事件的发布和订阅。 它提供了一种简洁…

讲一讲 kafka 的 ack 的三种机制?

大家好&#xff0c;我是锋哥。今天分享关于【K讲一讲 kafka 的 ack 的三种机制&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 讲一讲 kafka 的 ack 的三种机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka的消息确认机制&…

python实战项目46:selenium爬取百度新闻

python实战项目46:selenium爬取百度新闻 一、项目简介二、完整代码一、项目简介 思路是首先使用selenium打开百度新闻页面,然后实现翻页操作,获取每条新闻的标题和链接。接下来的问题是,在遍历标题和链接,对每一个链接发送请求时,发现会弹出百度安全验证,本文的思路是使…

远程root用户访问服务器中的MySQL8

一、Ubuntu下的MySQL8安装 在Ubuntu系统中安装MySQL 8.0可以通过以下步骤进行1. 更新包管理工具的仓库列表&#xff1a; sudo apt update 2. 安装MySQL 8.0&#xff0c;root用户默认没有密码&#xff1a; sudo apt install mysql-server sudo apt install mysql-client 【…

动态规划 - 背包问题 - 01背包

01背包问题 二维数组 1. 确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i][j]-下标为[0,i]的物品&#xff0c;任取放容量为j的背包中的最大价值 2. 确定递推公式&#xff1a;dp[i][j] max(dp[i-1][j]&#xff08;不放物品i), dp[i-1][j-weight[i]]…