网络IO模型之多路复用器.md

news2024/11/20 11:22:10

多路复用是什么?怎么理解?

本文主要涉及为

程序中处理网络IO时的模型,对于系统内核而言网络IO模型。这里只做普及使用

前置知识,什么是IO?怎么理解IO

IO其实就是In和Out。中文翻译是输入和输出,只要涉及到输入和输出的,我们都可以称之为IO。

例如你在磁盘中读取文件,读取文件为In,输出到其他地方为Out。

例如你Windows系统在网络通信时,读取客户端的输入数据包,这叫In,系统将数据包输出给我们编写的应用程序,这叫Out。

当然,我们如果成自身程序的角度去看网络通信的话,我们根据系统内核给予的文件描述符去获取TCP连接数据时,这就叫In,将数据输出到其他位置,这叫Out。

所以,我们可以总结,IO其实就是输入输出,它是对输入输出这个动作的统称,并不仅限于磁盘、网络等。

当然,IO相关的设备有很多,比如鼠标、触摸屏、NFC等

对于系统而言,处理IO有什么模型?

这里的系统,指的是Windows内核程序、Linux内核程序。

我们要知道,一个TCP连接到达服务器后,该连接是由系统内核程序进行管控的,它维护这条连接和上层应用与之交互的过程。

回到正题,我们今天说的是系统内核层面的IO模型情况,至于应用程序层的IO模型我会一笔带过。

同步模型

画个图更好理解:

这张图中,注意我们的业务程序中线程是需要不停的读取TCP连接通道中的数据,我们可以称之为为read操作。而本质上业务程序一直不停的主动读取数据的这种情况,本质上就是一个同步模型,因为始终是应用程序主动来读取的。

此时如果我们的线程,read数据没有的话,一直等待读取到数据的这个操作,对于我们业务程序而言,就是阻塞模型。而业务程序如果读取read后发现没有数据,直接跳过,这个就是非阻塞模型。至于业务程序读取到数据后,自身如何去操作,其实就是业务层面的同步和异步模型。

说到这里,你应该也明白了,系统内核层面的IO模型和我们业务程序层面的IO模型是可以完全不相关的。举个例子,我们先不谈系统内核层面,只说应用程序,应用程序读取到数据后,读取数据的线程用来处理业务,那就是同步模型;而应用程序读取数据的线程不参与业务处理,只处理网络连接的事情,当其他业务处理线程执行完业务逻辑后再让处理连接的线程响应数据,这就是异步模型。

那么此时你会有疑问,每次都要应用程序主动去读取,这太浪费资源了,应用程序能不能等数据来,而不是主动去找内核要,那么就代表着系统内核级别上有没有异步模型的存在?

实际上是有的,我们马上来描述。

异步模型

我们可以假想一下它的模型:

其实真实的内核异步网络IO的比这个图大很多,这里为了方便理解,做了一些简化。

从这张图我们可以知道,内核要实现异步的网络IO本身是可以实现的,但要注意,其实内核的异步IO应用并不广泛,原因如下:

1、内核实现难度增大,出问题的风险更大:内核要实现异步IO要比同步复杂得多,涉及到回调函数、事件循环等概念,要知道内核程序对稳定性要求极高,因为它是整个程序运行最基础的部分,增加复杂度则意味着增加风险。

2、性能考虑:虽然异步IO理论上可以提高性能,但在某些情况下,它可能不会带来显著的性能提升,尤其是当系统已经通过其他方式(如多线程或多路复用)进行了优化时。

3、内核实现限制:在Linux系统中,真正的异步IO模型发展面临一些挑战,特别是内核实现上的限制和历史遗留问题。例如,Linux的io_uring虽然是真在往异步IO发展,但在某些领域(如网络IO)还是基于epoll这种IO多路复用机制更加稳定和成熟。

等等还有很多理由可以说,总体来说,内核的异步IO应用不广泛主要是在于复杂度与稳定性上,但还有一个重要因素,也就是IO多路复用模型的实现。

IO多路复用模型

前面铺垫那么多,就是为了引出IO多路复用模型。

我们前面说了异步IO模型的本质是为了提高性能,而在内核层面上为了提高这个性能付出的代价未免太大了一点,那么就需要产生一个折中的办法。

这个折中的办法需要满足以下条件:

​ 1、应用程序不能一直去等待读取数据,节约线程资源。

​ 2、内核方面不能用异步操作,保持原来同步读的模型。

那么**【多路复用】**就能满足这两个条件,多路复用模型如图所示:

内核提供多路复用器,多路复用器中会监听各个网络TCP连接的状态,然后业务程序方面有专门的线程用来不停往多路复用器处查询连接状态,当发现有连接的状态发生变更后,就通知其他对应的线程去读取数据。

这样就达到了我们前面说的两个条件,应用程序无需一直反复尝试读取连接中的数据,而内核也无需实现异步模型。

在目前的环境下,绝大多数系统和应用都是使用这类模型来处理网络请求,例如Windows的IOCP,Linux的epoll,而业务程序方面代表性最强的则是Netty。

当然,多路复用可不是这一点讲清楚的,这里让大家对多路复用的基本原理有个了解,其实在上图中每一个涉及的点都有不同的实现方式,可以自行网上搜索了解下。

那么最后做个总结:

​ 1、业务程序自身处理IO和内核处理IO是无关的,本身是两个层面。

​ 2、内核层面绝大多数都是同步模型,此时加入多路复用后性能已经足够当下环境的需求,而异步模型由于复杂度和稳定性问题普及并不广泛。

​ 3、多路复用器不仅仅用于IO方面,其他很多场景都可以使用,所以多路复用器我们要理解其模型,而不能限定于IO。

​ 4、在Java层面,多路复用器在JVM的NIO包中已经实现好了,我们只管用就行,而当我们使用了Netty这类集成框架后,大多数情况下我们并不需要关系底层的内容

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js 递归调用 相同对象--数组递归调用

<div class="save-cl"> <a-button @click="saveCl" >保存为常用策略</a-button> </div> saveCl(){ console.log(this.form.filterList[0],--------常用策略)// 此对象为上图对象 console.log(this.allElementsHaveValue(thi…

【BUUCTF-PWN】7-[第五空间2019 决赛]PWN5

参考&#xff1a;BUU pwn [第五空间2019 决赛]PWN5 //格式化字符串漏洞 - Nemuzuki - 博客园 (cnblogs.com) 格式化字符串漏洞原理详解_printf 任意内存读取-CSDN博客 32位小端排序&#xff0c;有栈溢出保护 运行效果&#xff1a; 查看main函数 存在格式化字符串漏洞 输…

Ubuntu 22.04.4 LTS 安装配置 MySQL Community Server 8.0.37 LTS

1 安装mysql-server sudo apt update sudo apt-get install mysql-server 2 启动mysql服务 sudo systemctl restart mysql.service sudo systemctl enable mysql.service #查看服务 sudo systemctl status mysql.service 3 修改mysql root密码 #默认密码为空 sudo mysql …

数据结构(3.8)——栈的应用

栈在括号匹配中的应用 流程图 代码 #include <stdio.h> #include <stdlib.h> #define MaxSize 10typedef struct {char data[MaxSize];int top; } SqStack;// 初始化栈 void InitStack(SqStack* S) {S->top -1; // 初始化栈顶指针 }// 判空 bool StackEmpty(…

在线签约如何选择?2024年10款顶级app大比拼

支持电子合同签约的10大app&#xff1a;e签宝、上上签、DocuSign、契约锁、Adobe Sign、法大大、SignNow、安心签、HelloSign、PandaDoc。 无论是企业之间的交易还是个人服务合同&#xff0c;线上电子合同签约提供了一种便捷、高效且安全的方式来处理法律文档。本文将介绍几款优…

什么是YUV和IPB,PTS和DTS,视频编码解码过程

YUV 是一种在视频处理和压缩中常用的颜色空间。 它将图像的亮度 (Y) 与色度 (U 和 V) 成分分开。 这种分离对视频压缩和广播非常有益&#xff0c; 因为人眼对亮度变化比对颜色变化更敏感。 YUV 组件简介 Y (亮度)&#xff1a;表示图像的亮度或灰度信息。U (色度)&#xff1a;…

泛微开发修炼之旅--29用计划任务定时发送邮件提醒

文章链接&#xff1a;29用计划任务定时发送邮件提醒

华为云交付模式和技术支持

华为云交付模式概览 用户由于自身或者企业属性的原因&#xff0c;对于使用云服务的要求也会有所不同。因此&#xff0c;华为云针对于不同用户的不同要求&#xff0c;提供了以下三种交付模式供用户选择。 公有云模式 公有云的核心属性是共享资源服务华为公有云为个人和企业用户…

人工智能对网络安全有何影响?

人工智能网络安全在短期、中期和长期如何变化 当今数字时代网络安全的重要性 在谈论人工智能在网络安全中的作用时&#xff0c;必须首先考虑短期影响&#xff0c;因为它们是最明显的&#xff0c;而且它是一个未知的领域&#xff0c;需要超越直接炒作的能力。 因此&#xff0…

免费办公软件 -- LibreOffice v24.2.4

软件简介 LibreOffice是一款免费且开源的办公软件套件&#xff0c;它为个人和商业用户提供了一套完整的工具&#xff0c;用于处理文本文档、电子表格、演示文稿和其他类型的文件。这款软件兼容 Microsoft Office 的文件格式&#xff0c;如 .docx、.xlsx 和 .pptx&#xff0c;使…

go语言day08 泛型 自定义错误处理 go关键字:协程

泛型&#xff1a; 抛错误异常 实现error接口类型 用java语言解释的话&#xff0c;实现类需要重写error类型的抽象方法Error().这样就可以自定义异常处理。 回到go语言&#xff0c;在Error()方法中用*argError 这样一个指针类来充当error接口的实现类。 在f2()方法中定义返回值…

等保2.0标准相比之前的有哪些重大变化?

在数字化的浪潮中&#xff0c;网络安全如同一艘坚固的航船&#xff0c;承载着国家与民族的希望&#xff0c;驶向信息化的彼岸。等级保护制度&#xff08;等保&#xff09;作为中国网络安全的守护神&#xff0c;经过岁月的洗礼与智慧的积淀&#xff0c;迎来了等保2.0的时代&…

【Python】已解决:NameError: name ‘reload’ is not defined

文章目录 二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;NameError: name ‘reload’ is not defined 一、分析问题背景 在使用Python进行开发时&#xff0c;有时我们可能需要重新加载某个已经导入的模块&#xff0c;以便应用模块中的最…

CTFHUB-SSRF-数字IP Bypass

开启题目&#xff0c;页面空白 根据提示&#xff0c;不能使用点分十进制&#xff0c;尝试将127.0.0.1转换为十六进制形式&#xff0c;也就是0x7f000001 构造题目有所需 Payload ?url0x7f000001/flag.php 访问得到了flag 八进制&#xff1a;0177.000.000.001 十进制&#xf…

技术赋能政务服务:VR导视与AI客服在政务大厅的创新应用

在数字化转型的浪潮中&#xff0c;政务大厅作为服务民众的前沿阵地&#xff0c;其服务效率和质量直接影响着政府形象和民众满意度。然而&#xff0c;许多政务大厅仍面临着缺乏智能化导航系统的挑战&#xff0c;这不仅增加了群众的办事难度&#xff0c;也降低了服务效率。维小帮…

MySQL逻辑备份恢复实战之mysqldump与mysqlpump

MySQL逻辑备份介绍 逻辑备份&#xff1a; 备份内容&#xff1a;数据库的结构定义语句数据内容的插入语句&#xff0c;备份出来的文件是可以编辑的。 适用场景&#xff1a;数据量少的数据库&#xff0c;比较适合100G数据量以内的。 逻辑备份的特点&#xff1a; sql语句组成的…

Vue3进度条nprogress(手机端、PC端通用)

Vue3进度条nprogress是一个用于显示页面加载进度的库。要在Vue3项目中使用nprogress&#xff0c;需要先安装它&#xff0c;然后在你的项目中引入和使用。 安装nprogress npm install nprogress --save配置nprogress 在目录src下创建nprogress文件夹&#xff0c;里面创建nprogr…

Python面试宝典第6题:有效的括号

题目 给定一个只包括 (、)、{、}、[、] 这些字符的字符串&#xff0c;判断该字符串是否有效。有效字符串需要满足以下的条件。 1、左括号必须用相同类型的右括号闭合。 2、左括号必须以正确的顺序闭合。 3、每个右括号都有一个对应的相同类型的左括号。 注意&#xff1a;空字符…

开源协作wiki和文档软件Docmost

什么是 Docmost &#xff1f; Docmost 是一款开源协作 wiki 和文档软件。它是 Confluence 和 Notion 等软件的开源替代品。使用 Docmost 可以无缝创建、协作和共享知识。非常适合管理您的 wiki、知识库、文档等。目前 Docmost 处于测试阶段。 软件的主要特点 安装 在群晖上以 …

go 学习 之 HTTP微服务示例

1. 背景 学习ing 2. 创建文件&#xff1a;server.go go package mainimport ("github.com/gogf/gf/contrib/registry/file/v2""github.com/gogf/gf/v2/frame/g""github.com/gogf/gf/v2/net/ghttp""github.com/gogf/gf/v2/net/gsvc"&…