一文读懂I/O模型

news2024/12/28 19:33:01

什么是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模型,简称NIO,Non-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的区别


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划分


一个通俗例子读懂BIO、NIO、AIO
同步阻塞(blocking-IO)简称BIO
同步非阻塞(non-blocking-IO)简称NIO
异步非阻塞(asynchronous-non-blocking-IO)简称AIO
一个经典生活的例子:

小明去吃同仁四季的椰子鸡,就这样在那里排队,等了一小时,然后才开始吃火锅。(BIO)
小红也去同仁四季的椰子鸡,她一看要等挺久的,于是去逛会商场,每次逛一下,就跑回来看看,是不是轮到她了。于是最后她既购了物,又吃上椰子鸡了。(NIO)
小华一样,去吃椰子鸡,由于他是高级会员,所以店长说,你去商场随便逛会吧,等下有位置,我立马打电话给你。于是小华不用干巴巴坐着等,也不用每过一会儿就跑回来看有没有等到,最后也吃上了美味的椰子鸡(AIO)

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

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

相关文章

hjr-微服务(六):如何保障服务稳定性

服务稳定是一个特别大的话题,一般我们用SLA描述服务的质量 SLA一般有99.9 ,99.99,就是我们常说的三个9,四个9 有两个纬度衡量 时间纬度 请求纬度 请求的成功率计算方式:SL A 成功请求/(成功请求请求失败…

【计算机网络】IP协议

网络层 在复杂的网络环境中寻找一条合适的路径传输数据 IP协议 IP指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。设计IP的目的是提高网络的可扩展性:一是解决互联网问题,实现大规模、异构网络的互联互通…

【先进设备】仅3mm!超薄款,足底压力步态测量分析系统

产品介绍足底压力步态测量分析系统是一套可用于采集人体足底压力的装置系统,其采用了高密度薄膜压力传感器矩阵,实现足底压力分布数据自动采集和分析,兼具大量程、高采集频率、高精度、高可靠性等特点,可以采集不同疾病的步态及足…

表白生日祝福和3D表白相册

作者:BSXY_19计科_陈永跃BSXY_信息学院注:未经允许禁止转发任何内容表白生日祝福和3D表白相册1、效果与展示2、资源下载3、PC版本生日祝福4、手机版本生日祝福5、动态相册6、如何给别人看1、效果与展示 好友给了我一个链接,我点看一看原来都…

【操作系统】2、进程管理

文章目录二、进程管理2.1 进程、线程的基本概念2.1.1 进程的组成和特性2.1.2 进程的状态和转换2.1.3 进程控制(理解)2.1.4 线程的概念2.1.5 线程的实现方式2.1.5.1 用户级线程2.1.5.2 内核级线程2.1.5.3 多线程模式2.1 6 线程的状态与转换2.2 进程同步2.2.1 概念2.2.2 进程互斥…

gitee通过idea上传新的项目流程

gitee通过idea上传新的项目流程今天开始分享 一、gitee服务端处理 1、登录gitee 服务端,创建仓库 2、点击创建 点击创建 3、创建完成 4、点击复制此仓库的地址:https://gitee.com/nandao1/demo2.git 下面idea会用到 二、idea客户端处理 1、创建demo…

物流行业有什么重要的指标,如何进行数据分析?

大数据是信息时代的典型特征,即通过收集、输入、储存、管理、分析对传统数据进行整合,在互联网的发展中其重要作用。目前大数据已经应用在很多领域中,并影响着各行各业,也有越来越多的行业开始关注大数据,例如“菜鸟网…

C语言数组指针(指向数组的指针)详解

数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。以int arr[] { 99, 15, 100, 888, 252 };为例&am…

Homekit智能家居DIY-智能触摸面板开关

触摸开关,即通过触摸方式控制的墙壁开关,其感官场景如同我们的触屏手机,只需手指轻轻一点即可达到控制电器的目的,随着人们生活品质的提高,触摸开关将逐渐将换代传统机械按键开关。 触摸开关控制原理 触摸开关我们把…

VL6 多功能数据处理器

一、题目根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数,当select信号为0,输出a;当select信号为1,输出b;当select信号为2,输出ab;当select信号为…

5、排序与分页

文章目录1 排序数据1.1 排序规则1.2 单列排序1.3 多列排序2 分页2.1 背景2.2 实现规则2.3 拓展尚硅谷MySQL数据库教程-讲师:宋红康 我们缺乏的不是知识,而是学而不厌的态度 1 排序数据 1.1 排序规则 使用 ORDER BY 子句排序 ASC(ascend&…

MySQL安装教程(windows 64位)详细教程

1.确保电脑为64位系统 2.国外官网下载地址:MySQL : Download MySQL Community Server 2.1.点击下载之后,可以选择注册Oracle账号,也可以跳过直接下载 2.2.国内下载网址:Index of /mysql/MySQL-8.0/ 2.3.下载完成后解压到某一个文…

Qt 播放音频文件的几种方式

文章目录摘要1 QMediaPlayer1.1 播放音频文件1.2 播放视频文件1.3 我遇到的问题2 QSound3 QSoundEffect4 QAudioOutput关键字: Qt、 QSound、 QSoundEffect、 QMediaPlayer、 multimedia摘要 这篇文章至少拖了有一两个月了,这不阳了,在家实…

Linux的tree命令原来用处那么大,涨知识了!

大家应该熟悉或了解 Linux 中的目录结果,它就像树的根。这正是 tree 命令的概念。它以树状方式显示当前目录及其子目录的内容。 在使用 tree 命令之前,需要首先安装。 安装 tree 大多数 Linux 发行版中都没有预安装 tree 命令,但是可以在官…

XSS Game通关教程

12.XSS Game通关教程 1、Ma Spaghet! 审查源码 一个不安全的方式&#xff0c;直接get传输somebody 输入123看看位置 ?somebody123 如下 用下input标签即可 <input onmouseoveralert(1)>当鼠标移动到输入框时触发弹窗 2、Jefff 传入的jeff在eval里&#xff0c;那就…

MySQL(二)

schema与数据类型优化 数据类型的优化 更小的通常更好 应该尽量使用可以正确存储数据的最小数据类型&#xff0c;更小的数据类型通常更快&#xff0c;因为它们占用更少的磁盘、内存和CPU缓存&#xff0c;并且处理时需要的CPU周期更少&#xff0c;但是要确保没有低估需要存储的…

项目管理:产品新人常犯的四个错误

作为产品经理&#xff0c;在刚进入职场的时候总会遇到各种各样的困难&#xff0c;产品小白常犯的错误&#xff1a; 1、拿到需求就开始写方案 很多新人在接到一个需求时&#xff0c;常常犯的错误就是直接开始写产品需求文档。很多时候我们的需求来自于老板或者甲方&#xff0c;…

LeetCode-350. 两个数组的交集 II

目录方法一&#xff1a;哈希表方法二&#xff1a;排序 双指针题目来源 350. 两个数组的交集 II 方法一&#xff1a;哈希表 由于同一个数字在两个数组中都可能出现多次&#xff0c;因此需要用哈希表存储每个数字出现的次数。对于一个数字&#xff0c;其在交集中出现的次数等于…

看板:自我管理的高效工具!

当在团队中在做看板管理的时候&#xff0c;我们一直强调的是看板中的工作项需要承载价值。通过拉动承载价值的工作项在看板中的流动&#xff0c;我们可以清晰地看到产品价值从需求端流动到交付端的进展及状态。也正因如此&#xff0c;我们需要及时识别看板中没有价值的工作项并…

解锁极狐GitLab 自动化功能:Webhook 触发 Pipeline 与计划流水线

本文来自&#xff1a; 杨洪丽 极狐GitLab 高级网站可靠性工程师(SRE) 只使用极狐GitLab 存放代码? 那你就 OUT 啦&#xff01; 如果你也遇到了如图 A / B / C / D 各位同学的烦恼&#xff0c;不要错过这篇能够让你日常工作更高效的内容。 使用极狐GitLab Webhook 触发 Pipelin…