OS--常见的网络模型(包含IO多路复用的原理)
网络模型

IO模型主要就是用户空间和内核空间数据交换的形式。
IO模型
- 阻塞 I/O 模型(Blocking I/O)
- 应用程序发起 I/O 请求后,会被阻塞,直到 I/O 操作完成。
- 非阻塞 I/O 模型(Non-blocking I/O)
- 应用程序发起 I/O 请求后,不会阻塞,可以立即返回。如果 I/O 操作未完成,应用程序需要不断轮询检查 I/O 操作的状态。
- I/O 复用模型(I/O Multiplexing)
- 通过系统调用如
select、poll或epoll,应用程序可以同时监视多个 I/O 通道,当任何一个通道有数据可读或可写时,系统调用返回。
- 通过系统调用如
- 信号驱动 I/O 模型(Signal-Driven I/O)
- 应用程序发起 I/O 请求后,可以继续执行其他任务。当 I/O 操作完成时,操作系统会发送一个信号给应用程序,通知其 I/O 操作已经完成。
- 异步 I/O 模型(Asynchronous I/O)
- 应用程序发起 I/O 请求后,可以立即返回并继续执行其他任务。I/O 操作由操作系统在后台完成,完成后操作系统会通知应用程序。
阻塞IO
阻塞IO就是两个阶段都必须阻塞等待。

非阻塞IO
非阻塞IO的recvfrom操作会立即返回结果而不是阻塞用户进程。

虽然是非阻塞,但是性能并没有提升。而且忙等机制会导致CPU空转,CPU使用率暴增。
IO多路复用
比如服务器处理客户端Socket请求时,在单线程情况下,只能依次处理一个socket,如果正在处理的socket恰好未就绪(数据不可读或不可写),线程就会被阻塞,所有其他的线程客户端socket都必须等,性能自然会差。
如何提高效率呢?
- 方案一:使用多线程进行处理。
- 方案二:数据就绪了,用户就去读取数据。
那么如何知道内核中的数据就绪了?
文件描述符(File Descriptor) :简称FD,是一个从0开始递增的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)。
IO多路复用 : 是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。

recvfrom 只能监听一个fd,而select可以一次性传多个fd,效率比 recvfrom 高。
监听FD的方式、通知的方式又有多种实现,常见有:
- select
- poll
- epoll
差异:
- select和poll只会通知用户进程有FD就绪,但不确定具体是哪个FD,需要用户进程逐个遍历FD来确认
- epoll则会在通知用户进程FD就绪的同时,把已就绪的FD写入用户空间
select
select是Linux最早是由的I/O多路复用技术:
简单说,就是我们把需要处理的数据封装成FD,然后在用户态时创建一个fd的集合(这个集合的大小是要监听的那个FD的最大值+1,但是大小整体是有限制的 ),这个集合的长度大小是有限制的,同时在这个集合中,标明出来我们要控制哪些数据,
比如要监听的数据,是1,2,5三个数据,此时会执行select函数,然后将整个fd发给内核态,内核态会去遍历用户态传递过来的数据,如果发现这里边都数据都没有就绪,就休眠,直到有数据准备好时,就会被唤醒,唤醒之后,再次遍历一遍,看看谁准备好了,然后再将处理掉没有准备好的数据,最后再将这个FD集合写回到用户态中去,此时用户态就知道了,奥,有人准备好了,但是对于用户态而言,并不知道谁处理好了,所以用户态也需要去进行遍历,然后找到对应准备好数据的节点,再去发起读请求,我们会发现,这种模式下他虽然比阻塞IO和非阻塞IO好,但是依然有些麻烦的事情, 比如说频繁的传递fd集合,频繁的去遍历FD等问题

select模式存在的三个问题:
- 能监听的FD最大不能超过1024
- 发生2次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。
- 每次都要遍历所有FD来判断就绪装填
poll
poll 不再用 BitsMap 来存储所关注的文件描述符,取而代之用动态数组,以链表形式来组织,突破了select 的文件描述符个数限制,当然还会受到系统文件描述符限制。
poll模式问题:
- 使用「线性结构」存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。
epoll
先用epoll_create 创建一个 epol l对象 epfd,再通过 epoll_ctl 将需要监视的 socket 添加到epfd中,最后调用 epoll_wait 等待数据。

epoll 通过两个方面,很好解决了 select/poll 的问题。
- 第一点,epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过
epoll_ctl()函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删改一般时间复杂度是 O(logn)。而 select/poll 内核里没有类似 epoll 红黑树这种保存所有待检测的 socket 的数据结构,所以 select/poll 每次操作时都传入整个 socket 集合给内核,而 epoll 因为在内核维护了红黑树,可以保存所有待检测的 socket,所以只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。 - 第二点,epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用
epoll_wait()函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。

epoll 的 边缘触发和水平触发有什么区别?
- 使用边缘触发模式时,当被监控的 Socket 描述符上有可读事件发生时,服务器端只会从
epoll_wait中苏醒一次,即使进程没有调用read函数从内核读取数据,也依然只苏醒一次,因此我们程序要保证一次性将内核缓冲区的数据读取完。 - 使用水平触发模式时,当被监控的 Socket 上有可读事件发生时,服务器端不断地从
epoll_wait中苏醒,直到内核缓冲区数据被read函数读完才结束,目的是告诉我们有数据需要读取。
信号驱动IO
信号驱动IO是与内核建立SIGIO的信号关联并设置回调,当内核有FD就绪时,会发出SIGIO信号通知用户,期间用户应用可以执行其它业务,无需阻塞等待。

当有大量I0操作时,信号较多,SIGIO处理函数不能及时处理可能导致信号队列溢出
而且内核空间与用户空间的频繁信号交互性能也较低。
异步IO

相关文章:
OS--常见的网络模型(包含IO多路复用的原理)
网络模型 IO模型主要就是用户空间和内核空间数据交换的形式。 IO模型 阻塞 I/O 模型(Blocking I/O) 应用程序发起 I/O 请求后,会被阻塞,直到 I/O 操作完成。 非阻塞 I/O 模型(Non-blocking I/O) 应用程序…...
LCE(Local Cascade Ensemble)预测模型和LSTM(Long Short-Term Memory)模型在效果和特点上存在显著差异
LCE(Local Cascade Ensemble)预测模型和LSTM(Long Short-Term Memory)模型在效果和特点上存在显著差异。以下是对两者的比较: 一、效果比较 LCE模型: 优势:LCE结合了随机森林和XGBoost的优势&a…...
【mysql】约束的基本使用
文章目录 1. PRIMARY KEY 约束1.1 作用1.2 关键字1.3 特点1.4 添加主键约束1.5 关于复合主键1.6 删除主键约束 2. 自增列:AUTO_INCREMENT2.1 作用2.2 关键字2.3 特点和要求2.4 如何指定自增约束2.5 如何删除自增约束2.6 MySQL 8.0新特性—自增变量的持久化 3. FOREI…...
EasyExcel(二)导出Excel表自动换行和样式设置
EasyExcel(一)导出Excel表列宽自适应 背景 在上一篇文章中解决导出列宽自适应,然后也解决了导出列宽不可超过255的问题。但是实际应用场景中仍然会有导出数据的长度超过列宽255。这时导出效果就会出现如下现象: 多出列宽宽度的内容会浮出来,影响后边列数据的显示。 解决…...
农产品直播带货方案拆解
作为一名经验丰富的营销策划人道叔,今天我来拆解一下咱们4A营销广告圈的这份《直播天府川农好物带货方案》,让你能学到很多实用的策略和技巧,直接应用到你的策划工作中去。 首先,咱们看看背景分析。 助农直播现在可是个大热门&a…...
“**H5**” 和 “**响应式**” 是前端开发中常见的术语,但它们的概念和使用场景有所不同
“H5” 和 “响应式” 是前端开发中常见的术语,但它们的概念和使用场景有所不同。以下是它们的区别以及为什么为移动端开发的页面通常被称为 “H5” 的解释: 1. 为什么为移动端开发的叫 “H5”? “H5” 是 HTML5 的简称,HTML5 是…...
基于EasyExcel实现通用版一对一、一对多、多层嵌套结构数据导出并支持自动合并单元格
接口功能 通用 支持一对一数据结构导出 支持一对多数据结构导出 支持多层嵌套数据结构导出 支持单元格自动合并 原文来自:https://blog.csdn.net/qq_40980205/article/details/136564176 新增及修复 基于我自己的使用场景,新增并能修复一下功能&#x…...
Java堆内存分析
(一)、线上查看堆内存统计 # 命令用于打印堆内存中每个类的实例数量及其占用的内存,并且只包括活动对象(即存活的对象) jmap -histo:live <pid># 输出到文件方便查看 jmap -histo:live 12345 > aaa.txt(二)、下载dump文件࿰…...
maven高级(day15)
Maven 是一款构建和管理 Java 项目的工具 分模块设计与开发 所谓分模块设计,顾名思义指的就是我们在设计一个 Java 项目的时候,将一个 Java 项目拆分成多 个模块进行开发。 分模块设计我们在进行项目设计阶段,就可以将一个大的项目拆分成若干…...
计算机组成原理(九):乘法器
乘法器原理 乘法器的工作原理可以用二进制乘法来说明。二进制乘法和十进制乘法类似,通过部分积的累加得到结果。 部分积的生成 在二进制乘法中,每一位的乘积是两个二进制数位的 与运算(0 0 0,1 0 0,0 1 0&…...
python【输入和输出】
Python 有三种输出值的方式: 表达式语句print() 函数使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用。 ① 将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现: str(): 函数返回一个用户易…...
2024年华为OD机试真题-判断一组不等式是否满足约束并输出最大差-Python-OD统一考试(E卷)
最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述: 给定一组不等式…...
【json】
JSON JSON是一种轻量级的,按照指定的格式去组织和封装数据的数据交互格式。 本质上是一个带有特定格式的字符串(py打印json时认定为str类型) 在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互,类似于计算机普通话 python与json关系及相互转换…...
基于单片机的无线智能窗帘控制器的设计
摘 要 : 本文以单片机为控制核心 , 基于 PT2262/ 2272 无线收发模块 , 实现了窗帘的无线远程智能控制 . 该控制器通过高频无线收发模块实现了遥控窗帘的开合控制; 根据外部光线强弱实现自动开关窗帘 ; 根据设定时间自动完成开关过程; 通过语音播报当前环境温湿度信息以…...
磁盘满造成业务异常问题排查
最近遇到一个因为磁盘满导致的问题,分享一下,希望能够帮助到以后遇到同样问题的朋友。 早上突然收到业务老师反馈说:上传文件不能正常上传了。 想想之前都好好的,最近又没有更新,为什么突然不能使用了呢?…...
C++例程:使用I/O模拟IIC接口(6)
完整的STM32F405代码工程I2C驱动源代码跟踪 一)myiic.c #include "myiic.h" #include "delay.h" #include "stm32f4xx_rcc.h" //初始化IIC void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphCl…...
58.在 Vue 3 中使用 OpenLayers 绘制点、线、圆、多边形
前言 在现代 Web 开发中,地图功能已经成为许多应用的重要组成部分。OpenLayers 是一个强大的开源地图库,支持多种地图源和地图操作。结合 Vue 3 的响应式特性,我们可以轻松实现地图的交互功能。本文将详细介绍如何在 Vue 3 中使用 OpenLayer…...
如何快速上手一个鸿蒙工程
作为一名鸿蒙程序猿,当你换了一家公司,或者被交接了一个已有的业务。前辈在找你之前十分钟写了一个他都看不懂的交接文档,然后把一个鸿蒙工程交接给你了,说以后就是你负责了。之后几天你的状态大概就是下边这样的,一堆…...
c++入门之 命名空间与输入输出
1、命名空间 1.1使用命名空间的原因 先看一个例子: #include <iostream>int round 0;int main() {printf("%d", round);return 0; }请问,这个程序能跑起来吗? 答案是否定的 原因是,当我们想创建一个全局变量 …...
GRE技术的详细解释
GRE(Generic Routing Encapsulation,通用路由封装)是一种隧道协议,主要用于在不同网络之间封装和传输其他网络层协议的数据包。它最常用于在IP网络上建立虚拟点到点的隧道连接,是实现VPN的一项关键技术。 下面从原理、…...
OpenClaw学习助手:Qwen2.5-VL-7B自动解析教材插图
OpenClaw学习助手:Qwen2.5-VL-7B自动解析教材插图 1. 为什么需要AI学习助手 作为一名经常需要阅读大量技术文档的开发者,我发现自己经常陷入"读得快忘得更快"的困境。特别是遇到包含复杂图表和公式的教材时,手动整理关键信息要耗…...
Python绘图进阶:掌握颜色代码与实战应用
1. Python绘图中的颜色表示方法全解析 第一次用Python画图时,我对着那一堆颜色参数完全摸不着头脑。为什么同样的红色可以用"red"、"(1,0,0)"、"#FF0000"这么多种方式表示?后来才发现,这些不同的颜色表示方法各…...
终极指南:gin-vue-admin前端错误监控告警配置详解 - 邮件与钉钉实时通知方案
终极指南:gin-vue-admin前端错误监控告警配置详解 - 邮件与钉钉实时通知方案 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理&#…...
新手福音:用快马平台理解openclaw架构图并生成你的第一个应用
新手福音:用快马平台理解openclaw架构图并生成你的第一个应用 作为一个刚入门的开发者,第一次看到openclaw架构图时,那些方框和箭头让我一头雾水。直到在InsCode(快马)平台上动手实践后,才发现原来架构图可以这么直观。下面分享我…...
DLSS Swapper:3步解锁游戏性能倍增的AI优化工具
DLSS Swapper:3步解锁游戏性能倍增的AI优化工具 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper是一款专为PC游戏玩家设计的深度学习超级采样(DLSS)版本管理工具,通过智能环境诊断、…...
思维重构:三月七小助手如何重新定义星穹铁道游戏体验
思维重构:三月七小助手如何重新定义星穹铁道游戏体验 【免费下载链接】March7thAssistant 崩坏:星穹铁道全自动 三月七小助手 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant 在《崩坏:星穹铁道》的世界里࿰…...
Windows苹果设备驱动终极指南:3分钟搞定iPhone/iPad连接难题
Windows苹果设备驱动终极指南:3分钟搞定iPhone/iPad连接难题 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/…...
Flink的反压机制
目录 1. 什么是反压? 2. Flink 反压机制的演变 第一代:基于 TCP 的传播(Flink 1.5 之前) 第二代:基于信用制的反压(Flink 1.5+,当前版本) 3. 基于信用制的反压详解 核心组件 工作流程(对应上图) 优势 4. 如何识别和处理反压? 识别(通过 Flink Web UI) …...
遥感影像解译实战:从目视解译八要素到精准分类
1. 遥感影像解译的底层逻辑 第一次接触遥感影像时,我盯着屏幕上的彩色方块发懵——这堆像素点怎么能看出是森林还是农田?后来才发现,解译就像玩"大家来找茬",关键要掌握八要素这把万能钥匙。大小、形状、阴影、颜色、纹…...
10分钟零成本搭建KIMI AI免费API:个人智能助手完整指南
10分钟零成本搭建KIMI AI免费API:个人智能助手完整指南 【免费下载链接】kimi-free-api 🚀 KIMI AI 长文本大模型逆向API【特长:长文本解读整理】,支持高速流式输出、智能体对话、联网搜索、探索版、K1思考模型、长文档解读、图像…...
