几种IO模型

news2025/3/10 10:56:32

IO

真正的IO操作涉及到和IO设备的交互,而操作系统限制了应用程序直接和设备交互。我们通常说的IO操作实际上是应用程序和操作系统进行交互,一般会使用操作系统的System Call,即系统调用,读是read(),写是write(),不同的操作系统中实现可能有差异,但是功能是相同的。通过调用read,把数据从操作系统内核缓冲区复制到应用程序缓冲区;调用write,是把数据从应用程序缓冲区复制到操作系统内核缓冲区。真正与IO设备交互,是由操作系统在合适的时机发起系统中断,找到中断向量与对应的设备交互。
所以,IO分为两个阶段,一个是内核和设备交互阶段,另一个是内核和应用程序交互阶段。

同步IO与异步IO

同步IO是指用户线程是主动发起IO请求的一方,操作系统内核是被动接受IO请求的一方。
异步IO和同步IO相反,是指操作系统内核是主动发起IO请求的一方,用户线程是被动接受的一方。用户线程向内核注册了各种IO事件的回调函数,由内核去主动调用。

阻塞IO与非阻塞IO

阻塞IO指的是需要内核IO操作彻底完成后,才返回到用户线程继续执行。阻塞指的是用户程序的执行状态。
非阻塞IO指的是用户程序不需要等待内核IO操作彻底完成,在调用IO后内核会立即返回给用户线程一个状态值,用户线程可以继续往下执行,线程处于非阻塞的状态。

BIO

BIO即是blocking IO,同步阻塞性IO,应用程序从IO系统调用开始,直到系统调用返回,在这段时间内,用户线程是阻塞的。返回成功后,线程开始处理应用程序缓冲区数据。
假设现在用BIO模型读取磁盘上的一个文件:
(1)从read系统调用开始,用户线程就进入阻塞状态。
(2)当系统内核收到read系统调用,就开始准备数据。一开始,数据可能还没有到达内核缓冲区(可能没读完一个块),这时内核需要等待。
(3)内核一直等到完整的数据到达,将数据从内核缓冲区复制到应用程序缓冲区,之后read返回结果(返回复制到用户缓冲区中的字节数)。
(4)read返回后,用户线程会从阻塞中恢复,继续运行。

所以BIO模型在内核进行IO操作的两个阶段,用户线程都处于阻塞状态。
举个例子,小王去饭店吃饭,点了一份麻辣烫,然后他就一直盯着取餐口,直到老板向取餐口放置一份麻辣烫。之后,他去取来麻辣烫吃掉。
其中,小王就是应用程序,老板就是操作系统内核,点餐这个动作就是发起IO请求,取饭这个动作就是从内核缓冲区拷贝到进程缓冲区。

由于是小王发起点餐,所以这是同步的;但是小王一直盯着取餐口没有做其他事,说明他处于阻塞状态,所以这是同步阻塞IO模型。

NIO

Non-Blocking IO,非阻塞IO。在NIO模型中,应用程序的线程一旦开始IO系统调用,会出现以下两种情况:
(1)在内核缓冲区中没有数据的情况下,系统调用会立即返回,返回一个调用失败的信息。
(2)在内核缓冲区中有数据的情况下,则处于阻塞状态,直到数据从内核缓冲区复制到用户进程缓冲区完成后,系统调用返回成功,线程恢复运行。
假设现在用NIO模型读取磁盘上的一个文件:
(1)在内核数据没有准备好的阶段,用户线程发起IO请求时,立即返回。一般为了读取到最终的数据,用户线程需要不断地发起IO系统调用(while循环)。
(2)内核数据到达后,用户线程发起系统调用时,用户线程进入阻塞状态。内核开始复制数据,将数据从内核缓冲区复制到进程缓冲区,然后内核返回结果。
(3)用户线程读到数据后,解除阻塞状态,继续运行。也就是说,用户进程需要经过多次的尝试,才能保证最终真正读到数据,然后继续执行。

所以,NIO模型在操作系统与设备交互阶段,用户线程处于非阻塞状态,在操作系统与应用程序交互期间,用户线程需要阻塞以复制缓冲区。
还是小王去饭店吃饭,点了一份麻辣烫,在吃饭之前,他询问老板,饭好了吗,老板回复没有,然后他就每隔3分钟询问一次,直到饭做好了为止。之后,他去取来麻辣烫吃掉。

由于还是小王发起点餐,所以这是同步的;询问老板老板立即回复,说明是非阻塞的,所以这是同步非阻塞IO模型。

AIO

异步IO模型(Asynchronous IO,简称为AIO)。基本流程是:用户线程通过系统调用,向内核注册某个函数。内核在整个IO操作(包括数据准备、缓冲区数据复制)完成后,通知用户线程,执行后续的业务操作。在整个内核的数据处理过程中,包括内核将数据从网卡或磁盘读取到内核缓冲区、将内核缓冲区的数据复制到用户缓冲区两个阶段中,用户线程都不需要阻塞。
假设现在通过AIO模型来读取磁盘上的一个文件:
(1)当用户线程发起了read系统调用,可以继续往下执行,用户线程不阻塞,也不需要轮询来查询是否内核准备好了数据。
(2)内核开始IO的第一个阶段:与设备交互准备数据。等到数据准备好了,执行第二阶段,将数据从内核缓冲区复制到进程缓冲区。
(3)内核会给用户进程发送一个信号(Signal),或者回调用户线程注册的函数,通知用户线程read操作结束。
(4)用户线程读取进程缓冲区的数据,完成后续的业务操作。

所以,在AIO模型中内核等待数据和复制数据的两个IO阶段,用户线程都不阻塞。
假设现在饭店开始开放外卖服务,小王用外卖App点了份炒面并填写了住址,看到下单成功就干别的去了,然后外卖小哥把饭送到小王家门口,小王开心的吃了一顿美餐。

填写住址这个操作就相当于向内核中注册函数,从饭做好到外卖小哥送到家这两个过程小王也没有干等着,所以这是非阻塞的,所以整体上为异步IO模型。

IO多路复用

在IO多路复用模型中,引入了一种新的系统调用,称为选择器,功能是查询IO的就绪状态。在Linux系统中,对应的系统调用为select/epoll系统调用,epoll是select的增强版。通过该系统调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写),内核能够将就绪的状态返回给应用程序。之后,应用程序根据就绪的状态,进行相应的IO系统调用。
假设现在用IO多路复用模型编写一个socket监听服务器:
(1)注册IO操作。每收到一个客户端socket连接时将其注册到select/epoll选择器中。
(2)开始就绪状态的轮询。通过选择器的查询方法,查询注册过的所有socket连接的就绪状态。通过查询的系统调用,内核会返回一个就绪的socket列表。当任何一个注册过的socket中的数据准备好了,内核缓冲区有数据(就绪)了,内核就将该socket加入到就绪的列表中。
在轮询时,负责轮询的用户线程将会一直阻塞。
(3)用户线程获得了就绪状态的列表后,根据其中的socket连接,发起read系统调用,用户线程阻塞,内核开始将数据从内核缓冲区复制到进程缓冲区。
(4)复制完成后,内核返回结果,用户线程才会从阻塞中恢复继续执行。
假设小王,小张,小李去饭店吃饭,小王点了拉面,小张点了盖浇米饭,小李点了胡辣汤,这时他们雇了一个人帮他们查看饭的状态,如果谁的饭好了就通知某人去取饭。

这个过程中,三个人雇用的这个人就充当一个选择器,他需要不停的查看饭的状态,如果小王的饭好了就通知小王,然后小王去取饭,其他两人的饭也是如此,这就是IO多路复用。

总结

BIO、NIO在高并发场景下不可用,BIO需要一个线程维护一个IO连接,NIO需要不断轮询,占用CPU资源,NIO很少单独使用。
吞吐量最好的是AIO,其次是IO多路复用。
AIO目前只有windows的IOCP,linux下支持还不完善,所以跑在linux上的高并发网络应用程序大多采用IO多路复用模型。

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

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

相关文章

设计模式-结构型模式

目录 5.结构型模式 5.1 代理模式 5.1.1 概述 5.1.2 结构 5.1.3 静态代理 5.1.4 JDK动态代理 5.1.5 CGLIB动态代理 5.1.6 三种代理的对比 5.1.7 优缺点 5.1.8 使用场景 5.2 适配器模式 5.2.1 概述 5.2.2 结构 5.2.3 类适配器模式 5.2.4 对象适配器模式 5.2.5 应…

聊聊关于矩阵反向传播的梯度计算

目录 1. 前向传播 2. 反向传播 3. 矩阵反向传播 4. 总结 1. 前向传播 建立如图所示的简单网络 W 是权重矩阵,初始赋值为 2*2 的矩阵 X 是输入特征,初始赋值为 2*1 的矩阵 这样通过矩阵乘法 , Y WX ,应该得到一个 2*1 的输…

在这竞争激烈的时代,如何才能够在激烈竞争中脱颖而出呢

不管是在职场想要获得认可得到晋升,还是与客户谈合作;都需要你能够脱颖而出。让他人能够看到你并且认可你。那如何才能脱颖而出呢?首先你要先认识自己,知道自己有什么优势、劣势、技能、兴趣、爱好等等。明确自己有什么价值&#…

软件工程(1)--初识基础概念

前言 学习了半年的软件工程课程,总不能一无所获吧,故此写下文章总结一番。 软件工程是一门综合性交叉学科,它涉及计算机科学、工程科学、管理科学和数学等领域。学习目标是掌握需求分析、软件设计、编码风格、软件测试的工程化方法。 软件程序…

什么是股票量化研究?

谈到股票量化研究领域,肯定少不了有自动交易系统的支撑,像平时能将股票池中的数据挖掘出来也能熟能生巧的进行自助量化研究,包括数据接口系统的开发使用都是受到量化的影响,那么,如何看待股票量化研究?像平…

arm版(以uos为例)linux安装mysql8

官网下载:https://downloads.mysql.com/archives/community/上传到服务器,然后解压缩tar -zxvf mysql-8.0.31-linux-glibc2.17-aarch64.tar.gzmv mysql-8.0.31-linux-glibc2.17-aarch64 /usr/local/mysql-8创建MySQL数据目录mkdir -p /datacd datamkdir …

打通对账的最后一公里——对账管理平台

背景 日新月异的科技与快速变化的消费需求不断驱动零售模式的变革,实体商业与数字经济、传统零售与新零售,逐渐融合并形成了全渠道、一体化的发展趋势,也改变了以往企业认知中线上、线下渠道割裂的思维定式,零售快消类企业纷纷建…

电子技术——MOS管的物理特性

电子技术——MOS管的物理特性 增强型 MOSFET 是应用最广泛的场效应晶体管。除了最后一节,我们整章讨论的都是增强型 MOSFET 。我们从它的物理元件结构和物理操作入手,在下一节我们会在本节的基础上学习 MOSFET 的电流-电压特性。 元件结构 上图展示了n-…

Day876.redolog刷盘问题 -MySQL实战

redolog刷盘问题 Hi,我是阿昌,今天学习记录的是关于redolog刷盘问题的内容。 平时的工作中,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很…

RPA自动化办公07——Uibot流程加入python插件

参考:扩展UiBot命令_UiBot开发者指南 Uibot是非常方便,但是有些功能可能还需要别的语言来完成,例如python语言,作为胶水语言,在一个Uibot里面插入python脚本是很方便,好用的。 加入插件的位置 在新建一个流…

Seata分布式事务模式(TA、TCC、XA、SAGA)工作机制

前言 分布式应用痛点 分布式应用有一个比较明显的问题就是,一个业务流程通常需要几个服务来完成,业务的一致性很难保证。为了保障业务一致性,每一步都要在 catch 里去处理前面所有的“回滚”操作,可读性及维护性差,开…

分布式微服务

目录 认识微服务 单体服务架构的特点 分布式架构的特点 微服务 SpringCloud 总结 服务拆分及远程调用 服务拆分原则 假如在订单服务中,需要一起返回用户的信息 Eureka注册中心 Eureka的结构和作用 问题:order-service如何得知user-service实例…

基于拓扑的单树分割用于地面激光扫描点云的自动处理

Paper题目:Topology-based individual tree segmentation for automated processing of terrestrial laser scanning point clouds ABSTRACT 地面激光扫描 (TLS) 是一种基于地面的方法,可通过光探测和测距 (LiDAR) 技术快速获取 3D 点云。从 TLS 点云量…

搜索引擎关键字智能提示实践

为了提高阅读体验,请移步到:搜索引擎关键字智能提升实践一、背景搜索关键字智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,以提升用户使用体验。雪球以连接人与资产…

【K8S之调度器流程和扩展】如何给 scheduler 添加扩展插件、关闭默认插件、创建多个 scheduler?

参考 自定义 Kubernetes 调度器 阳明https://github.com/cnych/sample-scheduler-extender kube-scheduler 源码位置 kubernetes 调度器的源码位于 kubernetes/pkg/scheduler 中,大体的代码目录结构如下所示:(不同的版本目录结构可能不太一样) kuber…

如何检测文章被搜索引擎收录(如何让搜索引擎收录网站)

如何写网站内容才利于搜索引擎收录 网站关键词要想有好的排名,网站本身必须是被搜索引擎收录的状态,另外,网站上的相关内容收录越多,搜索引擎给与网站关键词的排名靠前概率会越大,那么,网站内容怎样来写会…

[Linux]生产者消费者模型(基于BlockQueue的生产者消费者模型 | 基于环形队列的生产者消费者模型 | 信号量 )

文章目录生产者消费者模型函数调用角度理解生产者消费者模型生活角度理解生产者消费者模型为什么要使用生产者消费者模型生产者消费者模型优点321原则基于BlockingQueue的生产者消费者模型POSIX信号量回顾信号量概念信号量操作函数环形队列基于环形队列的生产者消费者模型生产者…

Android Studio如何打jar包和aar包并使用

Android Studio如何打jar包和使用生成jar包方式module方式生成jar方式第一类修改主app的方式第二类:通过新建module方式生成jar包如何使用jar包aar生成并使用aar生成aar使用之前有篇文章介绍了so库的生成和使用,看这里,但是,如果我…

[NOI Online #1 入门组] 文具订购

题目描述: 小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品: 圆规,每个 7 元。笔,每支 4 元。笔记本,每本 3 元。 小明负责订购文具,设圆规,笔,笔记本的订购数量分别…

Linux 下安装 JDK 和 Maven 环境

目录 1. 进入 maven 官网下载安装包 2. 安装 maven 3. 添加 Maven 环境变量 4. 配置 Maven 本地仓库 5. 配置镜像 6. 配置 JDK 7. 测试 操作系统:Centos 7.6 安装 maven 环境前,需要先安装 java 环境,笔者这里已经成功安装 java 环境&…