【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.mzph.cn/news/662315.shtml

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

相关文章

2016年苏州大学837复试机试C/C++

2016年苏州大学复试机试 第一题 题目 公鸡5元一只,母鸡3元一只,幼鸡1元3只。若100元钱买了100只鸡,问其中公鸡、母鸡、幼鸡各多少只? 博主注:此题经典百元买百鸡问题,出自:公元5世纪末&#…

模拟钉钉官网动画

实现思路:利用粘性定位sticky,以及滚动事件实现。首先我们应该设置滚动动画开始位置和结束位置 ,然后根据位置计算透明度或者transform,scale的值。 首先根据上述图线计算属性值,代码如下: function creat…

PHP漏洞查询

CVE - Search CVE List (mitre.org) 美国国家漏洞数据库(需要梯子) NATIONAL VULNERABILITY DATABASE NVD - Search and Statistics (nist.gov) 基本都能查询到,传结果详情页里面会有一些解决方案的连接 PHP的官方网站 PHP :: Bugs :: Se…

C语言探索:水仙花数的奥秘与计算

摘要: 水仙花数,一种特殊的三位数,其各位数字的立方和等于该数本身。本文将详细介绍水仙花数的定义、性质,以及如何使用C语言来寻找100至999范围内的水仙花数。 目录 一、水仙花数的定义与性质 二、用C语言寻找100至999范围内的…

Camunda 流程引擎API介绍

💖专栏简介 ✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。 ✔️文章中只包含演示核心代码及测试数据,完整代码可查看作者的开源项目snail-camunda ✔️请给snail-camunda 点颗星吧😘 💖Services …

病历管理系统

技术架构: StrutsSpringHibernate 有需要该项目的小伙伴可以私信我你的Q。 功能描述: 企业财务管理系统主要用于电子病历来提高医院各项工作的效率和质量,促进医学科研、教学;减轻各类事务性工作的劳动强度,使他们…

LCR 193. 二叉搜索树的最近公共祖先

解题思路&#xff1a; 小的在左子树&#xff0c;大的在右子树。 class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root.val<p.val&&root.val<q.val)return lowestCommonAncestor(root.right,p,q);if(root.va…

深度揭秘:代理IP的工作原理及其在网络安全中的关键角色

代理IP的工作原理及其在网络安全中的关键角色是一个相对复杂但非常重要的主题。以下是对这一内容的深度揭秘&#xff1a; 代理IP的工作原理 1. 请求转发 当一个客户端&#xff08;如浏览器或爬虫程序&#xff09;使用代理IP时&#xff0c;它不是直接与目标网站通信&#xff0c…

2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码

2024美国大学生数学建模E题财产保险的可持续模型详解思路具体代码 前言 很快啊&#xff01;啪的一下拿到题目就开始做题&#xff01;简单介绍一下我自己&#xff1a;博主专注建模五年&#xff0c;参与过大大小小数十来次数学建模&#xff0c;理解各类模型原理以及每种模型的建…

Linux网络编程 基础

OSI七层模型 物理层&#xff1a;主要定义物理设备标准&#xff0c;如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流&#xff08;就是由1、0转化为电流强弱来进行传输&#xff0c;到达目的地后再转化为1、0&#xff0c;也就是我们常说的…

微信公众号公函公证书怎么弄?

公众号迁移有什么作用&#xff1f;只能变更主体吗&#xff1f;公众号迁移的作用可不止是变更主体哦&#xff01;有时候我们可能需要更换账号主体&#xff0c;但公众号是不支持直接变更的。这时候&#xff0c;我们就可以通过账号迁移功能&#xff0c;把 A 公众号的粉丝、违规记录…

C++中的字符串翻转算法解析

个人主页&#xff1a;[PingdiGuo_guo] 收录专栏&#xff1a;[C干货专栏] 大家好&#xff0c;今天我们来学一下C里的一个知识&#xff1a;字符串翻转。 目录 1.题目 描述 输入描述 输出描述 输入数据 1 输出数据 1 提示 2.解决题目 1.所需知识点 2.算法分析 1. 拼接…

演讲回顾:如何为大规模研发团队加速CI构建,实现高效流水线

近日&#xff0c;龙智联合Atlassian举办的DevSecOps研讨会年终专场”趋势展望与实战探讨&#xff1a;如何打好DevOps基础、赋能创新”在上海圆满落幕。龙智Atlassian技术与顾问咨询团队&#xff0c;以及清晖、JamaSoftware、CloudBees等生态伙伴的嘉宾发表了主题演讲&#xff0…

LLM App SDK:LangChain vs. LlamaIndex

在Why RAG is big中&#xff0c;我表示支持检索增强生成&#xff08;RAG&#xff09;作为私有、离线、去中心化 LLM 应用程序的关键技术。 当你建造一些东西供自己使用时&#xff0c;你就是在孤军奋战。 你可以从头开始构建&#xff0c;但在现有框架上构建会更有效。 NSDT工具推…

Java多线程--避免同步机制带来的死锁问题及用Lock锁解决线程安全问题

文章目录 一、死锁&#xff08;1&#xff09;说明&#xff08;2&#xff09;案例1、案例12、案例23、案例3 &#xff08;3&#xff09;诱发死锁的原因及解决方案1、诱发死锁的原因2、避免死锁 二、JDK5.0新特性&#xff1a;Lock(锁)&#xff08;1&#xff09;介绍&#xff08;2…

小白水平理解面试经典题目_数组类LeetCode 118 Pascal‘s Triangle【回归解法】

LeetCode 118 生成杨辉三角&#xff08;Pascal’s Triangle&#xff09; 小白渣翻译 给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 例子 这里是小白理解 那么这种题目一上来看&#xf…

4-树-合并两个有序链表

这是树的第4篇算法&#xff0c;力扣链接。 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xf…

Linux下gcc的使用与程序的翻译

gcc和程序的翻译过程 gcc介绍程序的翻译过程预编译编译汇编链接 命令行式宏定义 gcc介绍 gcc是一款编译C语言编译器&#xff0c;可以把我们用vim写的代码编译成可执行程序。编译C用g进行编译&#xff0c;C的文件后缀是test.cc或test.cpp或test.cxx 如果要安装g就执行以下命令 …

C# winform 多语言(json)方式实现

前后对比 使用nuget json工具包1.总体思路 创建对应的json字典对照表 { "测试":"Test", "语言":"Language", "设置":"Set", "中文(默认)":"Chinese (default)", "英文":"E…

【HarmonyOS应用开发】ArkTS 属性动画的使用(十二)

一、概述 属性动画&#xff0c;是最为基础的动画&#xff0c;其功能强大、使用场景多&#xff0c;应用范围较广。常用于如下场景中&#xff1a; 一、页面布局发生变化。例如添加、删除部分组件元素。二、页面元素的可见性和位置发生变化。例如显示或者隐藏部分元素&#xff0…