看一遍就理解:IO模型详解

news2024/9/30 1:36:03

大家好,今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~

什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll跟IO模型有什么关系?有几种经典IO模型呢?BIO、NIO、AIO到底有什么区别的?

如果这些问题,你都能很好答上的话,那恭喜你,你对IO的掌握已经很棒啦!那你跟田螺哥一起看完这篇文章,再复习一下,加深印象吧~如果你对这些问题模棱两可的话,那也没关系,看完这篇文章,就理解啦!

什么是IO呢?

IO,英文全称是Input/Output,翻译过来就是输入/输出。平时我们听得挺多,就是什么磁盘IO,网络IO。那IO到底是什么呢?是不是有种懵懵懂懂的感觉呀,好像大概知道它是什么,又好像说不清楚。

IO,即输入/输出,到底谁是输入?谁是输出呢?IO如果脱离了主体,就会让人疑惑。

计算机角度的IO

我们常说的输入输出,比较直观的意思就是计算机的输入输出计算机就是主体。大家是否还记得,大学学计算机组成原理的时候,有个冯.诺依曼结构,它将计算机分成分为5个部分:运算器、控制器、存储器、输入设备、输出设备。

图片

输入设备是向计算机输入数据和信息的设备,键盘,鼠标都属于输入设备;输出设备是计算机硬件系统的终端设备,用于接收计算机数据的输出显示,一般显示器、打印机属于输出设备。

例如你在鼠标键盘敲几下,它就会把你的指令数据,传给主机,主机通过运算后,把返回的数据信息,输出到显示器。

鼠标、显示器这只是直观表面的输入输出,回到计算机架构来说,涉及计算机核心与其他设备间数据迁移的过程,就是IO。如磁盘IO,就是从磁盘读取数据到内存,这算一次输入,对应的,将内存中的数据写入磁盘,就算输出。这就是IO的本质。

操作系统的IO

我们要将内存中的数据写入到磁盘的话,主体会是什么呢?主体可能是一个应用程序,比如一个Java进程(假设网络传来二进制流,一个Java进程可以把它写入到磁盘)。

操作系统负责计算机的资源管理和进程的调度。我们电脑上跑着的应用程序,其实是需要经过操作系统,才能做一些特殊操作,如磁盘文件读写、内存的读写等等。因为这些都是比较危险的操作,不可以由应用程序乱来,只能交给底层操作系统来。也就是说,你的应用程序要把数据写入磁盘,只能通过调用操作系统开放出来的API来操作。

  • 什么是用户空间?什么是内核空间?

  • 以32位操作系统为例,它为每一个进程都分配了4G(2的32次方)的内存空间。这4G可访问的内存空间分为二部分,一部分是用户空间,一部分是内核空间。内核空间是操作系统内核访问的区域,是受保护的内存空间,而用户空间是用户应用程序访问的内存区域。

我们应用程序是跑在用户空间的,它不存在实质的IO过程,真正的IO是在操作系统执行的。即应用程序的IO操作分为两种动作:IO调用和IO执行。IO调用是由进程(应用程序的运行态)发起,而IO执行是操作系统内核的工作。此时所说的IO是应用程序对操作系统IO功能的一次触发,即IO调用。

操作系统的一次IO过程

应用程序发起的一次IO操作包含两个阶段:

  • IO调用:应用程序进程向操作系统内核发起调用。

  • IO执行:操作系统内核完成IO操作。

操作系统内核完成IO操作还包括两个过程:

  • 准备数据阶段:内核等待I/O设备准备好数据

  • 拷贝数据阶段:将数据从内核缓冲区拷贝到用户进程缓冲区

图片

其实IO就是把进程的内部数据转移到外部设备,或者把外部设备的数据迁移到进程内部。外部设备一般指硬盘、socket通讯的网卡。一个完整的IO过程包括以下几个步骤:

  • 应用程序进程向操作系统发起IO调用请求

  • 操作系统准备数据,把IO外部设备的数据,加载到内核缓冲区

  • 操作系统拷贝数据,即将内核缓冲区的数据,拷贝到用户进程缓冲区

阻塞IO模型

我们已经知道IO是什么啦,那什么是阻塞IO呢?

假设应用程序的进程发起IO调用,但是如果内核的数据还没准备好的话,那应用程序进程就一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示,此次IO操作,称之为阻塞IO

图片

  • 阻塞IO比较经典的应用就是阻塞socket、Java BIO

  • 阻塞IO的缺点就是:如果内核数据一直没准备好,那用户进程将一直阻塞,浪费性能,可以使用非阻塞IO优化。

非阻塞IO模型

如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求。这就是非阻塞IO,流程图如下:

图片

非阻塞IO的流程如下:

  • 应用进程向操作系统内核,发起recvfrom读取数据。

  • 操作系统内核数据没有准备好,立即返回EWOULDBLOCK错误码。

  • 应用程序进程轮询调用,继续向操作系统内核发起recvfrom读取数据。

  • 操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间。

  • 完成调用,返回成功提示。

非阻塞IO模型,简称NIONon-Blocking IO。它相对于阻塞IO,虽然大幅提升了性能,但是它依然存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的CPU资源。可以考虑IO复用模型,去解决这个问题。

IO多路复用模型

既然NIO无效的轮询会导致CPU资源消耗,我们等到内核数据准备好了,主动通知应用进程再去进行系统调用,那不就好了嘛?

在这之前,我们先来复习下,什么是文件描述符fd(File Descriptor),它是计算机科学中的一个术语,形式上是一个非负整数。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

IO复用模型核心思路:系统给我们提供一类函数(如我们耳濡目染的select、poll、epoll函数),它们可以同时监控多个fd的操作,任何一个返回内核数据就绪,应用进程再发起recvfrom系统调用。

IO多路复用之select

应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据。

图片

非阻塞IO模型(NIO)中,需要N(N>=1)次轮询系统调用,然而借助select的IO多路复用模型,只需要发起一次询问就够了,大大优化了性能。

但是呢,select有几个缺点:

  • 监听的IO最大连接数有限,在Linux系统上一般为1024。

  • select函数返回后,是通过遍历fdset,找到就绪的描述符fd。(仅知道有I/O事件发生,却不知是哪几个流,所以遍历所有流

因为存在连接数限制,所以后来又提出了poll。与select相比,poll解决了连接数限制问题。但是呢,select和poll一样,还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,效率也会线性下降

因此经典的多路复用模型epoll诞生。

IO多路复用之epoll

为了解决select/poll存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现,流程图如下:

图片

epoll先通过epoll_ctl()来注册一个fd(文件描述符),一旦基于某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这里去掉了遍历文件描述符的坑爹操作,而是采用监听事件回调的机制。这就是epoll的亮点。

我们一起来总结一下select、poll、epoll的区别

selectpollepoll
底层数据结构数组链表红黑树和双链表
获取就绪的fd遍历遍历事件回调
事件复杂度O(n)O(n)O(1)
最大连接数1024无限制无限制
fd数据拷贝每次调用select,需要将fd数据从用户空间拷贝到内核空间每次调用poll,需要将fd数据从用户空间拷贝到内核空间使用内存映射(mmap),不需要从用户空间频繁拷贝fd数据到内核空间

epoll明显优化了IO的执行效率,但在进程调用epoll_wait()时,仍然可能被阻塞。能不能酱紫:不用我老是去问你数据是否准备就绪,等我发出请求后,你数据准备好了通知我就行了,这就诞生了信号驱动IO模型

IO模型之信号驱动模型

信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。

图片

信号驱动IO模型,在应用进程发出信号后,是立即返回的,不会阻塞进程。它已经有异步操作的感觉了。但是你细看上面的流程图,发现数据复制到应用缓冲的时候,应用进程还是阻塞的。回过头来看下,不管是BIO,还是NIO,还是信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的。还有没有优化方案呢?AIO(真正的异步IO)!

IO 模型之异步IO(AIO)

前面讲的BIO,NIO和信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的,因此都不算是真正的异步。AIO实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。

流程如下:

图片

异步IO的优化思路很简单,只需要向内核发送一次请求,就可以完成数据状态询问和数据拷贝的所有操作,并且不用阻塞等待结果。日常开发中,有类似思想的业务场景:

比如发起一笔批量转账,但是批量转账处理比较耗时,这时候后端可以先告知前端转账提交成功,等到结果处理完,再通知前端结果即可。

阻塞、非阻塞、同步、异步IO划分

图片

IO模型
阻塞I/O模型同步阻塞
非阻塞I/O模型同步非阻塞
I/O多路复用模型同步阻塞
信号驱动I/O模型同步非阻塞
异步IO(AIO)模型异步非阻塞

一个通俗例子读懂BIO、NIO、AIO

  • 同步阻塞(blocking-IO)简称BIO

  • 同步非阻塞(non-blocking-IO)简称NIO

  • 异步非阻塞(asynchronous-non-blocking-IO)简称AIO

一个经典生活的例子:

  • 小明去吃同仁四季的椰子鸡,就这样在那里排队,等了一小时,然后才开始吃火锅。(BIO)

  • 小红也去同仁四季的椰子鸡,她一看要等挺久的,于是去逛会商场,每次逛一下,就跑回来看看,是不是轮到她了。于是最后她既购了物,又吃上椰子鸡了。(NIO

  • 小华一样,去吃椰子鸡,由于他是高级会员,所以店长说,你去商场随便逛会吧,等下有位置,我立马打电话给你。于是小华不用干巴巴坐着等,也不用每过一会儿就跑回来看有没有等到,最后也吃上了美味的椰子鸡(AIO

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

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

相关文章

备考ICA----Istio实验9---熔断Circuit Breaking 实验

备考ICA----Istio实验9—熔断Circuit Breaking 实验 1. 环境准备 创建httpbin环境 kubectl apply -f istio/samples/httpbin/httpbin.yaml kubectl get svc httpbin2. 创建测试用客户端 kubectl apply -f istio/samples/httpbin/sample-client/fortio-deploy.yaml3. 创建Ht…

企业文件交换怎样进行有效防泄密管控?选对方案才能事半功倍

一、数据防泄密面临的挑战 数据流转才能释放价值,在企业生产经营中,数据和文件交换是业务有序开展的基础。文件交换会涉及不同的网络、系统及人员角色,存在泄露的安全风险;为此,不少企业采用或规划采用终端DLP、网络D…

C语言文件操作详解

文件是什么 在我们日常使用的电脑上我们在电脑磁盘上会看到许许多多的文件夹,那里面的东西其实就是文件,为什么我们要使用文件?那是因为我们的电脑肯定会要用来存储东西的,如果没有文件,那么我们的东西都全部存放在内…

ruoyi-nbcio-plus基于vue3的flowable其它元素(目前主要是元素文档)的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

借助剪映软件生成原创视频(真人人声,免VIP)

civilpy:借助各大模型的优点生成原创视频(真人人声)Plus0 赞同 0 评论文章​编辑 是的,剪映也出了声音克隆了,只需要十几秒的录音就可以克隆自己的声音,虽然微瑕,但是对于不习惯机器音的很多创…

python实战之基础篇

1. 注释 # coding utf-8 # 该注释放到文件第一行, 这个注释告诉python解释器该文件的编码集是UTF-82. 导入语句有三种形式 import <模块名> from <模块名> import <代码元素> from <模块名> import <代码元素> as <代码元素别名>3. 获取…

Spring Boot集成JPA快速入门demo

1.JPA介绍 JPA (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术&#xff0c;结束现在 Hibernate&#xff0c;TopLink&am…

Vue3状态管理库--Pinia

Pinia快速入门 一、什么是Pinia &#xff1f; Pinia 是 Vue 的专属的最新状态管理库 &#xff0c;是 Vuex 状态管理工具的替代品。 Pinia官网链接 提供更加简单的API &#xff08;去掉了 mutation &#xff09;提供符合组合式风格的API &#xff08;和 Vue3 新语法统一&…

微服务(基础篇-006-Docker)

Docker是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间没有任何接口&#xff08;类似 iPhone 的 app&…

使用第三方远程连接工具ssh连接vagrant创建的虚拟机

vagrant默认密码都是vagrant 密码认证默认是关闭的&#xff0c;进入虚拟机&#xff0c;打开密码认证 1、使用命令vi /etc/ssh/sshd_config进入配置&#xff0c;注意要切换到root用户&#xff0c;这个配置root有权限 2、找到PasswordAuthentication默认为no,改为yes 3、重启虚…

R: 网状Meta分析进行模型构建及图形绘制

网状meta分析的制作步骤主要包括&#xff1a; 1. 绘制网状证据图 2. 普通Meta分析&#xff08;两两之间的直接比较&#xff09; 3. 网状Meta分析&#xff08;整合直接比较和间接比较的结果&#xff0c;绘制相关图形&#xff09; 4. 绘制累积概率排序图 5. 三个假设的检验…

【独立开发前线】Vol.23 这个卖Excel课程的网站,月访问量14.5万,年销售额超过200万美金

今天要给大家分享的案例网站是&#xff1a;Miss-Excel 网址是&#xff1a;Miss Excel 这是一个专门销售Excel课程的网站&#xff0c;网址一共有18个系列的视频课程&#xff0c;最便宜的44美金&#xff0c;最贵的1197美金。所有的课程都是网站的创始人Kat Norton录制的&#xf…

SDSX-小米这篇论文牛吹大了,比SD1.5快30倍,比SDXL快60倍

今天在论文集上看到一篇很新的文章&#xff1a; SDXS: Real-Time One-Step Latent Diffusion Models with Image Conditions 大至意思就是&#xff0c;小米公司做了一个新的扩散模型&#xff0c;用的是蒸馏法&#xff08;参见turbo模型 及LCM模型)&#xff0c;速度很快&#…

文生视频大模型Sora的复现经验

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

QtCreator调试时无法显示std::string的内容

在银河麒麟V10或Ubuntu下使用QtCreator调试代码时&#xff0c;std::string类型变量在大多数情况下不显示实际内容&#xff0c;而是显示"<无法访问>"字样&#xff0c;鼠标点击进去也是看不见任何有用信息&#xff0c;这样非常影响调试效率&#xff0c;为此&…

docker 的网络管理

docker应用自带了三种类型的网络&#xff0c;然后我们自己也能自定义网络 roottest-virtual-machine:~# docker network ls NETWORK ID NAME DRIVER SCOPE 4c3e28760cff bridge bridge local afd1493dc119 host host local 5f200e2eaf22 n…

读所罗门的密码笔记04_社会信用

1. 人工智能 1.1. 人工智能可以帮助人们处理复杂的大气问题&#xff0c;完善现有的气候变化模拟&#xff0c;帮助我们更好地了解人类活动对环境造成的危害&#xff0c;以及如何减少这种危害 1.2. 人工智能也有助于减少森林退化和非法砍伐 1.3. 人工智能甚至可以将我们从枯燥…

argocd部署

一、前言 ArgoCD 是一个开源的、持续交付工具&#xff0c;用于自动化部署应用程序到 Kubernetes 集群。它基于 GitOps 理念&#xff0c;通过使用 Git 作为单一的源头来管理应用程序的配置和部署状态&#xff0c;argocd会定时监控git仓库中的yaml配置文件&#xff0c;当git仓库中…

uniapp 微信小程序 canvas 手写板文字重复倾斜水印

核心逻辑 先将坐标系中心点通过ctx.translate(canvasw / 2, canvash / 2) 平移到canvas 中心&#xff0c;再旋转设置水印 假如不 translate 直接旋转&#xff0c;则此时的旋转中心为左上角原点&#xff0c;此时旋转示意如图所示 当translate到中心点之后再旋转&#xff0c;此…

题目 3152: 蓝桥杯2023年第十四届省赛真题-接龙数列【DFS简单爆搜做法】

&#x1f44f;这个是目录哦~ DFS 只能拿到 1/4 的分数心路历程核心出装三大件get_first()get_last()dfs() 全部 DFS 只能拿到 1/4 的分数 心路历程 核心出装三大件 get_first() inline int get_first(int n) {//123//12//1while (n / 10) {n / 10;}return n; }get_last() in…