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

news2025/3/13 19:35:57

😁博客主页😁:🚀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.coloradmin.cn/o/1427248.html

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

相关文章

oracle 19c上安装样例数据库

样例schema的分类 HR: Human Resources OE: Order Entry PM: Product Media IX: Information Exchange SH: Sales History BI: Business Intelligence 安装样例数据库 1:HR的安装,通过dbca时候 2:HR的安装,安装完数据库后&#…

面试经典 150 题 -- 矩阵 (总结)

总的链接 : 面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台 36 . 有效的数独 模拟 : 用数组模拟哈希表来判断对应的行,列和当前元素所在的3*3方格中是否重复出现,是的话,直接return false…

vue3前端开发,element-plus前端框架探秘:scope对象

vue3前端开发,element-plus前端框架探秘:scope对象!我们经常需要对当前行的数据进行操作,比如增加,删除,编辑等,为此我们需要传递当前行所对应的唯一主键,通常情况下,当前行对应的业务主键是id属…

花瓣网美女图片爬取

爬虫基础案例01 花瓣网美女图片 网站url:https://huaban.com 图片爬取 import requests import json import os res requests.get(url "https://api.huaban.com/search/file?text%E7%BE%8E%E5%A5%B3&sortall&limit40&page1&positionsear…

【Linux-crontab】Linux 系统 crontab 执行定时任务

【Linux-crontab】Linux 系统 crontab 执行定时任务 1)crontab简介2)操作步骤3)知识扩展4)常见的分时任务格式 1)crontab简介 crond 是 Linux 下用来周期性的执行某种任务或等待处理某些事件的一个守护进程&#xff0…

专有D区震撼上市,高性价比的稀缺大机型谁不爱?

有时候,你可能想要一台或数台大机器: 核数多点,100不算多吧 内存大点,2T、4T的 主频高点,3.5GHz 要么三合一,既要又要还要? 那么问题来了: 这些既多核心,又大内存&a…

初学者必会的100个Python编程代码,入门全套资料都给朋友们整理好了,文末免费领!

我记得刚开始接触编程的时候,觉得太难了。 也很好奇,写代码的那些人也太厉害了吧?全是英文的,他们的英文水平一定很好吧? 他们是怎么记住这么多代码格式的?而且错了一个标点符号,整个程序都会…

Unity SRP 管线【第七讲:URP LOD实现以及Reflections反射探针】

目录 一、URP LOD 组件1、LOD Group的使用2、LOD切换原理Cross Fade(淡入淡出)模式Animated Cross-Fading如果未设置Clip,并且Fade Transition Width不为0LOD物体烘培 SpeedTree 模式 二、反射探针1. 获取反射探针数据2. 环境光照明 IBL3. 反射探针(Refl…

创业公司的项目经理,如何有效争取股权激励

摘要:PM圆桌派,思考要快,行动要快。希赛聚集了一群有追求的PM校友,在一起谈天说地。在这里,我们无问对错,不论输赢,不分高下,每周四,一期一个话题battle,将真…

LeetCode--189

189. 轮转数组 提示 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转…

ele-h5项目使用vue3+vite开发:第一节、页面头部实现

实现页面 确认需求 顶部提示栏搜索框搜索提示 normalize.css:处理不同浏览器的默认样式 安装 npm i normalize.css 使用 src\App.vue<style scoped> import normalize.css;#app {/** 让字体抗锯齿&#xff0c;看起来更清晰 */-webkit-font-smoothing: antialiased;-moz-o…

面试中问到的算法题。————目录树生成

前言 我在面试中遇到了算法题&#xff0c;也是我第一次面试&#xff0c;也不知道是太紧张了还是太久没刷算法题了&#xff0c;感觉压有点懵的状态&#xff0c;所以当时面试的时候没有做出来或者说只做了一半没有做完。 面试完成后&#xff0c;我又重新审视了一下题目&#xff…

【送书福利-第三十一期】《区块链安全理论与实践(安全技术经典译丛)》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

Xline Jepsen 测试分析

Table of Contents 摘要背景介绍 XlineJepsen CheckersNemesisJepsen 测试设计 数据一致性 SerializabilityLinearizabilityStrict SerializabilityJepsen etcd test RegistersSetsAppendWRJepsen Xline test测试结果分析 测试结果异步落盘Revision生成 背景旧的实现分析1-RTT…

九、Qt图表使用

一、QCharts概述 Qt图表提供了&#xff1a;折线图、样条曲线图、面积图、散点图、条形图、饼图、方块胡须图、蜡烛图、极坐标图。1、QChart介绍 Qt Charts基于Qt的QGraphics View架构&#xff0c;其核心组件是QChartView和QChartQChartView是显示图标的视图&#xff0c;基类为…

如何用gpt快速做好数据分析?

由于技术限制&#xff0c;目前InfinitePaper AI仅支持上传1份文件&#xff0c;且大小不超过10M。但是&#xff0c;在强大的代码解释器面前&#xff0c;这都是小问题。我们只需要将可能用到的文件打包成压缩文件上传即可&#xff0c;之后要求GPT直接解压就能正常完成后续需求。 …

Vue学习之使用HBuilderX创建并使用vue3.0项目

Vue学习之使用HBuilderX创建并使用vue3.0项目 下文将简述如何使用HBuilderX创建并使用vue3.0项目&#xff0c;包含项目创建、目录介绍、如何引用组件、首页自定义设置。 1、创建vue3.0项目 具体操作之前章节已经阐述过不在冗余介绍&#xff0c;创建时选择vue3项目即可。vue2…

2023年03月CCF-GESP编程能力等级认证Python编程二级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 以下存储器中的数据不会受到附近强磁场干扰的是( )。 A:硬盘 B:U 盘 C:内存 D:光盘 答案:D 第2题 下列流程图,属于计算机的哪种程序结构?( ) A:顺序结构 B:循环结构 C:…

《Lua程序设计》-- 学习10

环境&#xff08;Environment&#xff09; 具有动态名称的全局变量 全局变量的声明 由于Lua语言将全局变量存放在一个普通的表中&#xff0c;所以可以通过元表来发现访问不存在全局变量的情况。 正如前面所提到的&#xff0c;我们不允许值为nil的全局变量&#xff0c;因为值为…

C语言·贪吃蛇游戏(上)

1. 游戏任务 使用C语言在Windows环境的控制台中模拟实现小游戏贪吃蛇 游戏中要包含以下功能&#xff1a; 1. 贪吃蛇地图绘制 2. 贪吃蛇上下左右移动和吃食物 3. 蛇撞墙&#xff0c;或撞到自身死亡 4. 计算得分 5. 蛇身加速、减速 6. 暂停游戏 2. Win32 API 介绍 Windows是一种多…