【Linux C | I/O模型】Unix / Linux系统的5种IO模型 | 图文详解

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 Unix / Linux系统的5种IO模型🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
🕛发布时间🕛:2024-02-01 00:09:45

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
    • ✨1.1 什么是 I/O
    • ✨1.2 五种 I/O 模型介绍
  • 🎄二、阻塞I/O模型
  • 🎄三、非阻塞I/O模型
  • 🎄四、复用式I/O模型
  • 🎄五、信号驱动式I/O模型
  • 🎄六、异步I/O模型


在这里插入图片描述

🎄一、概述

✨1.1 什么是 I/O

I/OInput/Output 的缩写,意思是输入输出,一般指操作系统与硬件设备(磁盘、网卡)的数据写入或读取。常见的IO有以下两种:

  • 磁盘I/O:与磁盘的数据交互,读取磁盘数据写入数据到磁盘;在Linux编程中,可以使用open、read、write等函数来操作文件描述符实现与磁盘的数据交互。
  • 网络I/O:通过网卡与其他主机或本机其他进程的数据交互;在Linux编程中,可以使用socket、read、write等函数来操作套接字描述符实现网络I/O。

✨1.2 五种 I/O 模型介绍

在了解 I/O 模型之前,先看看操作系统是怎样与磁盘或网卡交换数据(操作I/O)的,一般分为两个步骤,下面以数据输入为例:

  • 1、等待数据到达网卡(或数据已存在与磁盘),将数据复制到内核的某个缓冲区;
  • 2、再将数据复制到应用层的进程的缓冲区。

之所以这样要分成这两个步骤去操作IO,是因为操作系统是分层的,有内核空间 和 用户空间,操作硬件设备都需要通过内核去操作,用户空间一般不直接操作硬件。
在这里插入图片描述

正是因为,数据从硬件设备到应用层缓冲区需要经过内核,所以存在一个等待的过程,这个过程被称为阻塞。由于这个阻塞的情况,再加上内核一些避免阻塞的机制,使 Unix / Linux 系统有5种 I/O 模型:

  • 阻塞I/O模型:一直等待数据到应用层缓冲区;
  • 非阻塞I/O模型:不等待数据完成,如果数据没到应用层就返回错误;
  • 复用式I/O模型:不等待数据完成,让其他系统调用帮忙等着;
  • 信号驱动式I/O模型:不等待数据完成,让内核准备好数据后就通知进程;
  • 异步I/O模型:告诉内核要读取哪些数据,让内读取完数据后再通知进程。

在这里插入图片描述


在这里插入图片描述

🎄二、阻塞I/O模型

阻塞I/O模型是使用得最多的IO模型,默认情况下,大部分IO操作都是阻塞的。

阻塞是指调用该系统调用后,需要等待内核获取完数据,再把数据复制到应用层缓冲区后,该系统调用才回返回。

如下图:应用层的进程调用recvfrom后,告诉内核要读取某个套接字的数据,内核就开始等待数据,等到数据准备好了,再将数据复制到应用层的用户空间,复制完成后,recvfrom函数读取到数据并返回。

在这里插入图片描述
阻塞I/O模型,就像你要去买奶茶,但前面很多人在买,你的奶茶没做好,你就一直在奶茶店等着你的奶茶,直到做好拿走。


在这里插入图片描述

🎄三、非阻塞I/O模型

进程把一个描述符fd设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠,才能完成时,不要把本进程投入睡眠,而是返回一个错误(EWOULDBLOCK)。EWOULDBLOCK这个单词由would block组成,表示告诉进程会阻塞

看下图,应用层的进程调用recvfrom获取数据时,因为内核准备好的数据,直接返回EWOULDBLOCK,紧接着,进程又调用recvfrom获取数据,内核仍没有准备好的数据,返回EWOULDBLOCK,前面三次都没有数据,知道第四次调用recvfrom获取数据时,内核的数据准备好了,将数据复制到用户空间,返回给应用的调用进程。

轮询:当一个进程对一个非阻塞的描述符循环调用recvfrom,称为轮询。应用程序持续轮询内核,会消耗大量的CPU时间,所以这样轮询访问数据的模型比较少用。轮询访问就类似下面伪代码。

while1{
	recvfrom(...);
	usleep(1000);
}

在这里插入图片描述
非阻塞I/O模型,就像你要去买奶茶,但前面很多人在买,你来拿奶茶时,奶茶店没做好,你就马上走了,过一会又来拿,又没做好,你又走了,过一会又来拿。。。这样循环来查看奶茶做好了没,直到某一次,奶茶做好了,你就拿走。


在这里插入图片描述

🎄四、复用式I/O模型

I/O复用(I/O multiplexing),可以让我们阻塞在其他系统调用函数上,而不是阻塞在真正的I/O系统调用上。但是阻塞在其他系统调用函数也还是阻塞啊,有什么区别吗?区别在于,如果需要对多个(大于1个)描述符进行IO操作时,select或poll系统调用可以同时监控多个描述符是否可读、可写,而阻塞IO只要阻塞在那就干不了其他事情了。

下图使用select函数演示复用I/O模型,应用层进程调用select系统调用,并将感兴趣的描述符通知内核,内核等待数据到达,发现select函数感兴趣的描述符的数据准备好了,就马上让select返回该描述符可读,然后进程再调用recvfrom函数来获取数据,因为此时数据已准备好,所以内核直接将数据复制到用户空间,返回给recvfrom的调用进程。
在这里插入图片描述
复用式I/O模型,就像你要去买奶茶,但前面很多人在买,你就花钱找了个黄牛,帮你在那里等,奶茶做好之后,黄牛就打电话让你来拿。


在这里插入图片描述

🎄五、信号驱动式I/O模型

信号驱动式I/O模型,让内核在描述符的数据准备好的时候发SIGIO信号给进程,进程再调用recvfrom函数来获取数据。

信号驱动式IO是指进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程。

针对一个套接字使用信号驱动式IO (SIGIO)要求进程执行以下3个步骤。
(1)建立SIGIO信号的信号处理函数。
(2)设置该套接字的属主,通常使用fcntl的F_SETOWN命令设置。
(3)开启该套接字的信号驱动式IO,通常通过使用fcnt1的F_SETFL命令打开O_ASYNC标志完成。

下图:先建立了SIGIO信号处理函数并设置其他配置,然后使用sigaction注册SIGIO的处理函数到内核,内核数据准备好了就会给该进程发送SIGIO信号,进程接收SIGIO信号后,进入SIGIO的信号处理函数,然后会调用recvfrom函数,此时数据已准备好,所以内核直接将数据复制到用户空间,返回给recvfrom的调用进程。

在这里插入图片描述信号驱动式I/O模型,就像你要去买奶茶,但前面很多人在买,你不想等,于是,你把手机号码给到奶茶店,等奶茶做好了,店主给你打电话,你再去拿奶茶。


在这里插入图片描述

🎄六、异步I/O模型

异步I/O(asynchronous I/O)的工作机制是:告知内核启动某个I/O操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。这种模型与信号驱动式I/O模型的主要区别在于:信号驱动式IO是由内核通知我数据准备好了,可以读取了;而异步I/O通知到进程时,数据已经读取完了。

在这里插入图片描述
异步I/O模型,就像你要去买奶茶,但前面很多人在买,你不想等,就干脆点外卖,等奶茶做好了,直接送到你手里,不需要你再去店里拿了。


在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考资料:
《Unix网络编程卷1》
https://blog.csdn.net/qq_54015483/article/details/131013426
https://blog.csdn.net/qq_54015483/article/details/130943574
https://blog.csdn.net/Bb15070047748/article/details/124699009

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式学习 Day16

一. 共用体 形式: union 共用体名 { 成员列表; //各个变量 }; //表示定义一个共用体类型 注意: 1.共用体 初始化 --- 只能给一个值,默认是给到第一个成员变量的 2.共用体成员变量 共用体用的数据最终存储的 --…

了解Ansible自动化运维工具及模块的使用

一、Ansible的相关知识 1.1 Ansible工具的了解 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。Ansible…

aspose-words基础功能演示

我们在Aspose.Words中使用术语“渲染”来描述将文档转换为文件格式或分页或具有页面概念的介质的过程。我们正在讨论将文档呈现为页面。下图显示了 Aspose.Words 中的渲染情况。 Aspose.Words 的渲染功能使您能够执行以下操作: 将文档或选定页面转换为 PDF、XPS、H…

gitlab操作手册

git操作篇 1. 项目克隆 git clone gitgitlab.test.cn:pro/project1.git2. 项目的提交 注:如果要查看文件的状态可以用git status命令: 如上图所示,文件已经修改了。 3. 项目的推送 git push origin feature/test01注:如果要查…

【遥感入门系列】遥感分类技术之遥感解译

遥感的最终成果之一就是从遥感图像上获取信息,遥感分类是获取信息的重要手段。同时遥感图像分类也是目前遥感技术中的热点研究方向,每年都有新的分类方法推出。 本小节主要内容: 遥感分类基本概念常见遥感分类方法 1 遥感分类概述 遥感图…

【Qt】Json在Qt中的使用

Json JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于互联网应用程序之间的数据传输。JSON基于JavaScript中的对象语法,但它是独立于语言的,因此在许多编程语言中都有对JSON的解析和生成支持。…

C++ 音视频流媒体浅谈

C流媒体开发 今天就浅浅聊一下C流媒体开发 流媒体开发中最常见的是FFmpeg(编解码器) 业务逻辑主要是播放器了(如腾旭视频 爱奇艺等等) FFmpeg是一个开源的音视频处理工具集,可以用于处理、转换和流媒体传输音视频…

python-自动化篇-办公-文件-加解密

解说 要使⽤Python进⾏⽂件的加密和解密,可以使⽤第三⽅加密库,如cryptography或pycryptodome。 ⼀个基本的⽰例,演⽰如何使⽤cryptography库对⽂件进⾏加密和解密: 安装cryptography库: pip install cryptography⽂…

运行程序时出现“无效类”的解决方法

最近做开发时,遇到了一个奇怪的问题,打开的烧录软件突然出现了“无效类”的字样,以前打开却时正常的,真的是莫名其妙。 然后找了很久的解决办法,终于在某一天运行一个系统软件出现了同样的问题,有提示到WMI…

Kore.ai获10亿元融资,提供定制化类ChatGPT助手

1月31日,生成式AI和企业对话平台Kore.ai在官网宣布,获得1.5 亿美元(约10.7亿元)融资。本次由FTV Capital 领投,英伟达等跟投。 Kore.ai主要提供银行、医疗、零售、营销、人力资源等多种领域的,定制化类Cha…

【Qt学习笔记】(二)信号和槽

信号和槽 1 信号和槽概述2 信号和槽的使用3 可视化生成槽函数4 自定义信号和槽5 带参数的信号和槽6 信号与槽的连接方式7 信号与槽的断开8 使用 Lambda 表达式来定义槽函数 1 信号和槽概述 在Qt中,用户和控件的每次交互过程称为一个事件。比如"用户点击按钮&q…

在Android Studio中配置OpenCV

在Android Studio中配置OpenCV 1 下载OpenCV2 导入OpenCV模块3 修改配置4 增加依赖5 拷贝libopencv_java.so6 Activity中加入代码1 下载OpenCV 下载OpenCV的Android包并解压。 2 导入OpenCV模块 在Android应用中,导入OpenCV模块。 导入目录时选择Opencv Android中的sdk目…

杠杆交易在伦敦金市场的优势与风险

伦敦金作为黄金市场的灯塔,每天吸引着全球投资者的目光。伦敦金的特殊地位使得以它为基准的杠杆交易成为众多投资者追逐的目标。在这篇文章中,我们将深入探讨伦敦金杠杆交易的奥秘,带你揭开这一盛宴的神秘面纱。 伦敦金杠杆交易的核心在于通过…

bs4模块

bs4模块与案例 使用指南 bs4,全称BeautifulSoup 4,是Python中一个强大的网页解析库,它可以帮助我们方便地从网页中提取数据。bs4将复杂HTML文档转换成树形结构,每个节点都是Python对象,所有对象可以归纳为4种&#xf…

vue动态修改侧边菜单栏宽度

1.添加可修改宽度的dom元素 <div style"background: #f5f7fa;padding: 20px 10px;"><label>菜单宽度 </label><el-input v-model"sideWidth" placeholder"请输入宽度值" style"width: 100px"/> px<el-but…

PMP认证是如何评估项目管理能力的?

当提及项目管理能力时&#xff0c;PMP认证是广泛接受的评估标准。作为项目管理领域的权威认证&#xff0c;PMP评估了申请人在项目管理方面的专业能力和实践经验。那么&#xff0c;PMP认证如何评估项目管理能力呢&#xff1f;本文将揭示PMP认证的评估体系和流程。 PMP认证的评估…

Notion 开源替代品:兼容 Miro 绘图 | 开源日报 No.162

toeverything/AFFiNE Stars: 25.6k License: NOASSERTION AFFiNE 是下一代知识库&#xff0c;将规划、排序和创建集于一身。它是一个注重隐私、开源、可定制且即插即用的替代方案&#xff0c;可以与 Notion 和 Miro 相媲美。主要功能和优势包括&#xff1a; 超融合&#xff1…

Android系统-应用程序中的View框架

源码分析基于Android 7 应用程序中的View框架如图所示 1. View和ViewRoot 单单从名称看很容易让人产生误解&#xff0c;因为ViewRoot并不属于View树的一分子。源码上ViewRoot和View对象也没有继承关系。更准确说ViewRoot理解为View输的管理者&#xff0c;ViewRoot有一个mView成…

apk反编译修改教程系列---修改apk的默认颜色 布局颜色 手机电脑同步演示【十】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…

【Tomcat与网络11】如何自己实现一个简单的HTTP服务器

在前面我们尝试解释Tomcat的理论&#xff0c;但是呢&#xff0c;很多时候那些复杂的架构和设计会让我们眼花缭乱&#xff0c;以至于忽略了最进本的问题——服务器到底是什么&#xff1f;今天我们就用尽量简单的代码实现一个简易的HTTP服务器。 HTTP启动之后要持续监听&#xf…