5种IO模型

embedded/2025/1/12 15:11:36/

目录

  • 一、认识IO
  • 二、5种IO模型
  • 三、非阻塞IO代码

一、认识IO

什么是IO? Input(输入)和Output(输出)。

冯诺依曼体系结构中,数据从输入设备拷贝到内存,经过处理后,再从内存拷贝到输出设备。现实情况中,数据并不是那么流畅的进行拷贝操作,而是会进行“等”。比如系统调用recv,当读取条件不满足时,它就会阻塞,当读取条件满足了,拷贝数据并返回结果。

所以总结一下,recv一共就做了两件事:等+拷贝 => IO=等+拷贝

其他系统调用也是一样,比如send,当发送缓冲区满了,就会阻塞,直到有空间腾出来,才能进行发送数据。

什么是高效IO? 单位时间内,等的比重越低,IO效率越高
高效的IO代码: 减少IO的比重或者等的时间利用起来

二、5种IO模型

1️⃣阻塞IO
在这里插入图片描述

内核准备好数据之前,系统调用会一直等待

2️⃣非阻塞IO
如果系统调用一直长时间等下去,对CPU来说是较大的浪费。
在这里插入图片描述
如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK 错误码。返回的间隙应用进程可以做别的事情。

3️⃣信号驱动IO
在这里插入图片描述
数据准备好了,内核发送信号通知应用进程可以进行IO操作了。

4️⃣多路转接IO
在这里插入图片描述
与阻塞IO类似,区别在于多路转接IO可以同时等待多个fd的就绪状态。

5️⃣异步IO
在这里插入图片描述
由内核完成数据的拷贝,然后通知应用进程来处理数据(注意:信号驱动IO是发送信号告诉应用进程什么时候来拷贝数据)

阻塞IO与非阻塞IO
等的方式不一样,前者干等,后者轮询式的等待,期间可以做别的事情
同步IO与异步IO
阻塞IO、非阻塞IO、信号驱动IO和多路转接IO是同步IO,最后一个是异步IO。同步IO应用程序的系统调用都有参与IO的操作,异步IO拷贝数据时是内核来完成的
谁最高效?
多路转接IO最高效,栗子:200个人(为一个整体)钓鱼与一个人钓鱼,200个人中任意一个人钓上鱼的概率比一个人钓上鱼的概率要大

三、非阻塞IO代码

系统调用:fcntl

设置非阻塞:

void SetNonblock(int fd)
{int fl = fcntl(fd, F_GETFL);if(fl < 0){return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}

1️⃣阻塞IO代码

#include "Comm.hpp"
int main()
{char buffer[1024];while (true){ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;cout << "echo# " << buffer << endl;}else{cout << "读取错误..." << endl;sleep(1);}}return 0;
}

在这里插入图片描述
没有数据等待用户输入,有数据就打印数据

2️⃣非阻塞IO代码

#include "Comm.hpp"
int main()
{char buffer[1024];SetNonblock(0);// 设置非阻塞while (true){ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;cout << "echo# " << buffer << endl;}else{cout << "读取错误..." << endl;sleep(1);}}return 0;
}

在这里插入图片描述

怎么知道是IO条件不就绪,还是读取错误?
打印返回值:

#include "Comm.hpp"
int main()
{char buffer[1024];SetNonblock(0);// 设置非阻塞while (true){ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;cout << "echo# " << buffer << endl;}else{cout << "读取错误... , s: " << s << endl;sleep(1);}}return 0;
}

在这里插入图片描述

注意:IO条件不就绪和读取错误的返回值是一样的

打印错误码:

#include "Comm.hpp"
int main()
{char buffer[1024];SetNonblock(0);// 设置非阻塞while (true){ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;cout << "echo# " << buffer << endl;}else{cout << "读取错误... , s: " << s << " errno: " << errno << endl;sleep(1);}}return 0;
}

在这里插入图片描述
说明是底层IO条件不就绪导致的:

#include "Comm.hpp"
int main()
{char buffer[1024];SetNonblock(0);// 设置非阻塞while (true){ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;cout << "echo# " << buffer << endl;}else{if(errno == EWOULDBLOCK || errno == EAGAIN){cout << "IO条件不就绪, 下次再试下" << endl;sleep(1);continue;}cout << "读取错误..."<< endl;sleep(1);}}return 0;
}

在这里插入图片描述
如果有输入数据,这些数据会被按顺序读取,按回车后通过显示器设备打印出来(显示器也有输入缓冲区和输出缓冲区)


http://www.ppmy.cn/embedded/153307.html

相关文章

sqlzoo答案2-SELECT from WORLD Tutorial

在sqlzoo练习sql&#xff1a;SELECT from WORLD Tutorial - SQLZoo namecontinentareapopulationgdpAfghanistanAsia6522302550010020343000000AlbaniaEurope28748283174112960000000AlgeriaAfrica238174137100000188681000000AndorraEurope468781153712000000AngolaAfrica124…

Decord - 深度学习视频加载器

文章目录 一、关于 Decord初步基准 二、安装1、通过pip安装2、从源代码安装2.1 Linux2.2 macOS2.3 Windows 三、用法1、VideoReader2、VideoLoader3、AudioReader4、AVReader 四、深度学习框架的桥梁&#xff1a; 一、关于 Decord 一款高效的深度学习视频加载器&#xff0c;具…

RK3568-rk809rtc休眠唤醒

参考链接 https://www.360doc.cn/article/71858349_1119199262.html修改驱动drivers/mfd/rk808.c static void rk817_shutdown_prepare(void) { int ret; …

nginx负载均衡-基于端口的负载均衡(一)

注意&#xff1a; (1) 做负载均衡技术至少需要三台服务器&#xff1a;一台独立的负载均衡器&#xff0c;两台web服务器做集群 一、nginx分别代理后端web1 和 web2的三台虚拟主机 1、web1&#xff08;nginx-10.0.0.7&#xff09;配置基于端口的虚拟主机 [rootOldboy extra]# …

C# 或 .NetCore 如何使用 NPOI 导出图片到 Excel 文件

今天在本文中&#xff0c;我们将尝试使用NPOI库将图像插入到 Excel 文件的特定位置。请将以下逻辑添加到您的写作方法中&#xff0c;在 Excel 文件中添加图像&#xff08;JPEG、PNG&#xff09;,我已经有一个示例 jpeg 文件 - Read-write-excel-npoi.jpg &#xff0c;我们将尝试…

车载数据结构 --- ARXML VS JSON

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

在Ubuntu中使用systemd设置后台自启动服务

引言 在Ubuntu系统中&#xff0c;systemd 是一个非常强大的系统和服务管理器。它不仅负责系统的启动和初始化&#xff0c;还可以帮助我们管理各种后台服务。通过使用 systemd&#xff0c;我们可以轻松地设置服务在系统启动时自动运行&#xff0c;并且能够方便地管理服务的启动…

大模型算法工程师相关面试

文章目录 一、深度学习与大模型基础二、大模型前沿与应用三、工程与系统设计四、实战与项目经验五、总结与面试准备建议 由于大模型&#xff08;如大语言模型、Vision Transformer 等&#xff09;通常具有参数量巨大、数据依赖度高、训练及推理过程复杂等特点&#xff0c;因此在…