当前位置: 首页 > news >正文

【linux高级IO(一)】理解五种IO模型

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:Linux从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学更多操作系统知识
  🔝🔝


在这里插入图片描述

Linux高级IO

  • 1. 前言
  • 2. 重谈对IO的理解
  • 3. 阻塞IO讲解
  • 4. 非阻塞IO讲解
  • 5. 信号驱动IO
  • 6. IO多路转接
  • 7. 异步IO
  • 8. 理解异步和同步
  • 9. 总结以及拓展

1. 前言

本篇文章开始, 将与大家分享高级IO相关的内容
本章重点:

本篇文章会带大家初识五种常见的IO模型, 分别是: 阻塞IO, 非阻塞IO, 信号驱动IO, IO多路转接, 异步IO. 其中, 多路转接将会是本系列文章后续的重点


2. 重谈对IO的理解

IO: input or output --> 访问外设 效率低
IO一定是非常低效的, 以读取为例:

当我们read/recv时, 如果底层缓冲区没有数据, read/recv函数会阻塞
当我们read/recv时, 如果底层缓冲区有数据, read/recv函数会拷贝

所以说, IO = 等待 + 拷贝 !!!

记住这句话, 会一直贯穿整个IO系列文章

探讨低效IO和高效IO:

很明显, IO = 等待 + 拷贝.
所以可以得出下面的结论:

  • 低效IO: 单位时间内, 大部分时间, IO类接口都在等待
  • 高效IO: 让等待的比重降低

接下来的五种IO模型, 就是围绕着是否高效进行的


3. 阻塞IO讲解

正如其名, 阻塞IO 在内核将数据准备好之前, 系统调用会一直等待, 并且所有的套接字默认都是阻塞IO. 阻塞IO是最常见的IO模型, 它比较好理解, 下面是关于阻塞IO的图像讲解

在这里插入图片描述

通俗来讲, 阻塞IO就是, 你去河边钓鱼, 只拿一根鱼竿等于上钩, 并且时刻盯着水面


4. 非阻塞IO讲解

顾名思义, 非阻塞IO就是说, 当底层数据没有准备就绪时, 不会傻傻的等待, 而是直接返回. 但是调用recv时, 出现错误也会直接返回, 应该怎样区分这两种情况呢? 答案是阻塞式IO的正常返回时, 会将errno全局遍历设置为宏: EWOULDBLOCK. 这下就能将它们区分开了

在这里插入图片描述

非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一般只有特定场景下才使用. 下面是非阻塞IO的简单示例:

#include <fcntl.h>
#include <unistd.h>
#include<errno.h>
#include <cstdlib>
#include <iostream>
using namespace std;//对指定的fd设置非阻塞
void SetNonBlock(int fd) {int fl = fcntl(fd, F_GETFL);if (fl < 0) {cerr << "fcntl error" << endl;exit(1);}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}int main() {SetNonBlock(0);while (1) {char buffer[1024];ssize_t s = read(0, buffer, sizeof(buffer) - 1);if (s > 0) {buffer[s] = 0;cout << buffer << endl;} else if (s == 0) {cout << "读到文件结尾了" << endl;break;}else{//1. 数据没用准备好 2. 真的出错了. 都以-1的返回值返回// 数据没有准备好,不算出错. 需要区分这两种情况if(errno == EWOULDBLOCK || errno == EAGAIN){cout<<"os底层数据还没就绪"<<endl;cout<<errno<<endl;}//被信号中断, 也不算read出错else if(errno == EINTR){cout<<"IO interrupted by signal"<<endl;}else{cout<<"read error"<<endl;break;}}sleep(1);}
}

调用fcntl函数将fd设置为非阻塞

通俗来讲, 非阻塞IO就是, 你去河边钓鱼, 也只用一根鱼竿, 但是你过一分钟才去看看有没有鱼上钩, 其他时间你可能在刷抖音


5. 信号驱动IO

信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作. 也就是说信号驱动的方式你不用像非阻塞IO一样, 每过一段时间去检查是否有数据就绪, 一旦有数据就绪, 会有信号通知你, 这也就可以更多时间刷抖音了(不是)

在这里插入图片描述

通俗来讲, 信号驱动IO就是, 你去河边钓鱼, 也只拿一个鱼竿, 只不过鱼竿上有压力传感器, 一旦有鱼上钩就会发出声音提醒你. 其余时间我们当然可以愉快的刷抖音


6. IO多路转接

前面几个钓鱼的人是不是有点寒酸了?一次只拿一个鱼竿, 效率太低了吧! 多路转接直接把桌子掀了, 它拿了100个鱼竿去钓鱼: IO多路转接能够同时等待多个文件描述符的就绪状态

在这里插入图片描述

通俗来说就是你拿一百个鱼竿去钓鱼, 同时等待一百种可能, 一旦有鱼上钩了, 会同时把所有上钩的鱼都拉上来, 这效率简直是指数级增长, 所以这也是在实际生活中使用的最多的IO方案


7. 异步IO

前面所有的IO方式, 都是同步IO, IO=等待+拷贝, 同步IO就是要么参与了等待过程, 要么参与了拷贝过程, 要么都参与了. 而异步IO则是等待和拷贝都不参与: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据).

在这里插入图片描述

还是拿钓鱼的例子来说, 前面的钓鱼者, 不管你一次性带多少鱼竿(多路转接), 不管你在鱼竿上安装什么高科技(信号驱动), 但是你总得去河边, 自己拿着鱼竿钓鱼. 而异步IO是怎么做的呢? 他直接雇佣了一个人帮它去钓鱼, 什么时候鱼上钩, 你等待了多久我都不在乎, 我只需要你在晚上九点的时候将钓的鱼全部带给我即可.


8. 理解异步和同步

同步和异步关注的是消息通信机制.

在这里插入图片描述

同步和异步在实际场景中怎样运用?

虽然说大部分IO类型都是同步IO, 但是实际生活中运用异步IO的概率也不小. 举个例子, 你是王者荣耀的后端, 一个英雄放了一个技能打在对面身上, 此时我们后端要将这个操作做成同步的还是异步的? 很明显是同步, 因为我想要实时的看见对面英雄的血条在减少. 再举个例子, 现在你是QQ的后端, 你现在要查询一千万个QQ号中, 有哪些QQ号超过1个月没有上线了. 你把此功能做成同步还是异步? 很明显考虑到成本问题一定是做成异步, 一千万个QQ号如果用一台机器可能会查询几个小时, 你可能会说, 那我可以用多台机器做负载均衡, 是的没错, 但是机器数量多了, 成本就上去了. 所以做成异步的IO比较好

综上所述, 实际场景中要根据自己的情况和需求来觉得使用同步还是异步, 不要觉得在学习时都用同步, 以后工作了也就无脑的用同步


9. 总结以及拓展

本篇文章只是简单的介绍了IO模型的几个分类, 其中, 最重要的模型是多路转接, 后面的文章会着重讲解它. 多路转接为什么重要? 因为它是业内最常用的用来提高并发性的模型, 后续大家都接触都reactor模型, 而reactor模型可以有多种实现方式, 而效率最高的reactor模型则是用多路转接实现的!!!


🔎 下期预告:多路转接之select 🔍

相关文章:

【linux高级IO(一)】理解五种IO模型

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux高级IO 1. 前言2. 重谈对…...

前端引用vue/element/echarts资源等引用方法Blob下载HTML

前端引用下载vue/element/echarts资源等引用方法 功能需求 需求是在HTML页面中集成Vue.js、Element Plus&#xff08;Element UI的Vue 3版本&#xff09;、ECharts等前端资源&#xff0c;使用Blob下载HTML。 解决方案概述 直接访问线上CDN地址&#xff1a;简单直接&#xff0c…...

昇思MindSpore学习笔记2-01 LLM原理和实践 --基于 MindSpore 实现 BERT 对话情绪识别

摘要&#xff1a; 通过识别BERT对话情绪状态的实例&#xff0c;展现在昇思MindSpore AI框架中大语言模型的原理和实际使用方法、步骤。 一、环境配置 %%capture captured_output # 实验环境已经预装了mindspore2.2.14&#xff0c;如需更换mindspore版本&#xff0c;可更改下…...

uniapp实现图片懒加载 封装组件

想要的效果就是窗口滑动到哪里&#xff0c;哪里的图片进行展示 主要原理使用IntersectionObserver <template><view><image error"HandlerError" :style"imgStyle" :src"imageSrc" :id"randomId" :mode"mode&quo…...

持续交付:自动化测试与发布流程的变革

目录 前言1. 持续交付的概念1.1 持续交付的定义1.2 持续交付的核心原则 2. 持续交付的优势2.1 提高交付速度2.2 提高软件质量2.3 降低发布风险2.4 提高团队协作 3. 实施持续交付的步骤3.1 构建自动化测试体系3.1.1 单元测试3.1.2 集成测试3.1.3 功能测试3.1.4 性能测试 3.2 构建…...

VBA常用的字符串内置函数

前言 在VBA程序中&#xff0c;常用的内置函数可以按照功能分为字符串函数、数字函数、转换函数等等&#xff0c;本节主要会介绍常用的字符串的内置函数&#xff0c;包括Len()、Left()、Mid()、Right()、Split()、String()、StrConV()等。 本节的练习数据表以下表为例&#xff…...

大数据面试题之Spark(7)

目录 Spark实现wordcount Spark Streaming怎么实现数据持久化保存? Spark SQL读取文件&#xff0c;内存不够使用&#xff0c;如何处理? Spark的lazy体现在哪里? Spark中的并行度等于什么 Spark运行时并行度的设署 Spark SQL的数据倾斜 Spark的exactly-once Spark的…...

AI绘画 Stable Diffusion图像的脸部细节控制——采样器全解析

大家好&#xff0c;我是画画的小强 我们在运用AI绘画 Stable Diffusion 这一功能强大的AI绘图工具时&#xff0c;我们往往会发现自己对提示词的使用还不够充分。在这种情形下&#xff0c;我们应当如何调整自己的策略&#xff0c;以便更加精确、全面地塑造出理想的人物形象呢&a…...

liunx离线安装Firefox

在Linux系统中离线安装Firefox浏览器&#xff0c;您需要先从Mozilla的官方网站下载Firefox的安装包&#xff0c;然后通过终端进行安装。以下是详细的步骤&#xff1a; 准备工作 下载Firefox安装包&#xff1a; 首先&#xff0c;在一台可以上网的电脑上访问Firefox官方下载页面…...

UNet进行病理图像分割

数据集链接&#xff1a;https://pan.baidu.com/s/1IBe_P0AyHgZC39NqzOxZhA?pwdnztc 提取码&#xff1a;nztc UNet模型 import torch import torch.nn as nnclass conv_block(nn.Module):def __init__(self, ch_in, ch_out):super(conv_block, self).__init__()self.conv nn…...

初二数学基础差从哪开始补?附深度解析!

有时候&#xff0c;当你推不开一扇门的时候&#xff0c;不要着急&#xff0c;试着反方向拉一下&#xff0c;或者横向拉一下。下面是小偏整理的初二数学基础差从哪开始补2021年&#xff0c;感谢您的每一次阅读。   初二数学基础差从哪开始补2021年   第一个问题是很多同学都…...

【C语言】return 关键字

在C语言中&#xff0c;return是一个关键字&#xff0c;用于从函数中返回值或者结束函数的执行。它是函数的重要组成部分&#xff0c;负责将函数的计算结果返回给调用者&#xff0c;并可以提前终止函数的执行。 主要用途和原理&#xff1a; 返回值给调用者&#xff1a; 当函数执…...

华为机试HJ13句子逆序

华为机试HJ13句子逆序 题目&#xff1a; 将一个英文语句以单词为单位逆序排放。例如“I am a boy”&#xff0c;逆序排放后为“boy a am I”所有单词之间用一个空格隔开&#xff0c;语句中除了英文字母外&#xff0c;不再包含其他字符 想法&#xff1a; 将输入的字符串通过…...

代码随想录day40 动态规划(5)

52. 携带研究材料&#xff08;第七期模拟笔试&#xff09; (kamacoder.com) 完全背包&#xff0c;可重复放入物品&#xff0c;需要用一维滚动数组从前往后遍历。 由于第0个物品和后面物品的转移方程没有区别&#xff0c;可以不额外初始化dp数组&#xff0c;直接用元素全0的d…...

FFmpeg 命令行 音视频格式转换

&#x1f4da;&#xff1a;FFmpeg 提供了丰富的命令行选项和功能&#xff0c;可以用来处理音视频文件、流媒体等&#xff0c;掌握命令行的使用&#xff0c;可以有效提高工作效率。 目录 一、视频转换和格式转换 &#x1f535; 将视频文件转换为另一种格式 &#x1f535; 指定…...

Jmeter使用JSON Extractor提取多个变量

1.当正则不好使时&#xff0c;用json extractor 2.提取多个值时&#xff0c;默认值必填&#xff0c;否则读不到变量...

c++ 设计模式 的课本范例(下)

&#xff08;19&#xff09; 桥接模式 Bridge&#xff0c;不是采用类继承&#xff0c;而是采用类组合&#xff0c;一个类的数据成员是类对象&#xff0c;来扩展类的功能。源码如下&#xff1a; class OS // 操作系统负责绘图 { public:virtual ~OS() {}virtual void draw(cha…...

结合数据索引结构看SQL的真实执行过程

引言 关于数据库设计与优化的前几篇文章中&#xff0c;我们提到了数据库设计优化应该遵守的指导原则、数据库底层的索引组织结构、数据库的核心功能组件以及SQL的解析、编译等。这些其实都是在为SQL的优化、执行的理解打基础。 今天这篇文章&#xff0c;我们以MySQL中InnoDB存…...

spark shuffle——shuffle管理

ShuffleManager shuffle系统的入口。ShuffleManager在driver和executor中的sparkEnv中创建。在driver中注册shuffle&#xff0c;在executor中读取和写入数据。 registerShuffle&#xff1a;注册shuffle&#xff0c;返回shuffleHandle unregisterShuffle&#xff1a;移除shuff…...

HTMLCSS(入门)

HTML <html> <head><title>第一个页面</title></head><body>键盘敲烂&#xff0c;工资过万</body> </html> <!DOCTYPE>文档类型声明&#xff0c;告诉浏览器使用哪种HTML版本显示网页 <!DOCTYPE html>当前页面采取…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...