Linux - 五种常见I/O模型

I/O操作 (输入/输出操作, Input/Output) 是指计算机与外部设备就行数据交互的过程.

什么是外部设备: 如键盘, 鼠标, 硬盘, 网卡等.

五种常见的 I/O 模型:

  1. 阻塞 I/O
  2. 非阻塞 I/O
  3. 信号驱动 I/O
  4. I/O 多路复用
  5. 异步 I/O

阻塞 I/O

阻塞 I/O 的特点: 当用户发起 I/O 请求后, 进程/线程就会被阻塞, 直到这个 I/O 操作完成.

1. 发起 I/O 请求 ( read/write ).

2. 如果数据为准备好, 那么进程/线程就会被阻塞, 进入等待状态

3. 数据准备好了, 操作系统将数据复制到用户空间, 进程/线程获取到了数据, 就被唤醒继续执行

就像是一个人去钓鱼, 当他甩鱼竿之后, 就一直盯着鱼竿什么都不做, 直到看见有鱼上钩了, 将鱼竿收起来.

阻塞 I/O: 实现简单, 容易理解.

缺点: 但是效率低下, 因为进程/线程会一直等待 I/O 操作完成, 等待期间不会执行其他的任务, 资源的利用率低.

非阻塞 I/O

上面了解了阻塞 I/O 是一直等待 I/O 操作完成形成阻塞.
那么非阻塞 I/O 也就是当进程/线程发起 I/O 请求后, 即使数据没有准备好, 也会立即返回. 不会被阻塞住.

1. 进程/线程发起非阻塞 I/O

2. 如果数据未准备好, 操作系统就会返回一个错误

3. 进程或线程需要不断的轮询, 检查数据是否准备好

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>#define BUFFER_SIZE 1024int main() {char buffer[BUFFER_SIZE];int flags;// 获取标准输入的文件描述符的当前标志flags = fcntl(STDIN_FILENO, F_GETFL, 0);if (flags == -1) {perror("fcntl F_GETFL");return 1;}// 设置标准输入为非阻塞模式if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) == -1) {perror("fcntl F_SETFL");return 1;}while (1) {// 尝试从标准输入读取数据ssize_t n = read(STDIN_FILENO, buffer, BUFFER_SIZE - 1);if (n == -1) {if (errno == EAGAIN || errno == EWOULDBLOCK) {// 没有数据可读,进行其他操作printf("No input available, doing other work...\n");sleep(1);} else {perror("read");break;}} else if (n > 0) {// 读取到数据,处理数据buffer[n] = '\0';printf("Read input: %s", buffer);} else {break;}        }return 0;
}

可以看到代码中对于 read 函数的操作需要使用循环不断的检查数据是否准备完成. 这个不断循环的过程就称为轮询.

就像去钓鱼, 我不会一直在那盯着鱼竿, 而是每过一会就去看看有没有鱼上钩, 在这期间可以去看看手机, 刷刷视频.

优点: 如果检测到数据还没准备好, 那么此时程序也可以执行一些耗时不长的任务, 这也是非阻塞 I/O 的一个优点.

缺点: 轮询机制会占用大量的 CPU 资源, 效率低下.

信号驱动 I/O

基于信号通知进程/线程 I/O 操作完成.

1. 程序注册一个信号处理器

2. 当数据准备好了, 操作系统就会发送对应的信号通知程序

3. 程序接收到信号后, 信号处理器就会执行对应操作

钓鱼的时候, 每过一段时间就去看看太麻烦了, 所以在鱼竿上装了一个铃铛, 当有鱼咬钩时, 铃铛就会响. 铃铛响将相当于是信号. 铃铛不响我就继续做我自己的事, 看看手机....

优点: 这也是非阻塞的一个 I/O 模型, 有着非阻塞 I/O 的优点. 通过信号可以准确快速的响应 I/O 事件.

缺点: 那么引入了信号, 程序就必然会变得更加复杂, 容易出现错误.

I/O 多路复用

上面的 I/O 模型中, 都是对某一个 I/O 操作进行管理. 

I/O 多路复用则是对于多个 I/O 操作进行管理, 当某个 文件描述符(fd) 准备好了后, 系统就会发送通知, 此时程序就可以对这些 准备好了的 fd 进行操作

1. 通过 select, poll 或 epoll 监控多个文件描述符 (fd) 的状态

2. 当有 fd 准备好了后, 操作系统通知程序, 程序就对这些准备好的 fd 进行操作

上面钓鱼中, 我只带了一根钓鱼竿 , 那么现在我带了50根钓鱼竿, 50根杆同时钓鱼, 效率大幅提升.

异步 I/O

前面的四种都是同步 I/O. I/O = 等待 + 拷贝. 同步 I/O 至少参与了一个过程 (等待或拷贝).

而异步 I/O 则是两个都不参加. 有操作系统完成 I/O 操作, 操作系统完成后通知进程/线程. 进程/线程可以通过回调函数或事件通知机制获取本次 I/O 操作的结果.

1. 用户进程/线程发起异步 I/O 请求, 直接返回

2. 操作系统负责完成 I/O 操作, 并在完成后通知用户进程/线程

3. 用户线程通过回调函数或事件通知机制获取本次 I/O 结果

之前钓鱼, 都是自己在操作, 但是现在我雇佣一个人来帮我钓鱼, 当他钓鱼结束后, 将钓到的鱼交给我就行, 我不用去管钓鱼的事.

当然这一种模型也很复杂的. 对于程序员的要求较高

同步和异步

同步: 必须等待任务完成后, 才能执行下一个任务. 像上面的四种 I/O 模型中, 无论是阻塞还是非阻塞, 我们都在等待它的返回值 (等待它执行的结果). 只有等到了它执行的结果, 程序才会继续向下执行. 异步也是不断地继续轮询, 直到等到执行的结果

异步: 则不会等待这个任务, 而是继续向后执行. 如异步的进行 I/O 请求, 虽然也会直接进行返回, 但是这个返回并没有附带本次操作的结果. 重点并不是返回, 重点是本次请求的结果是否被等待了. 至于本次任务执行的结果, 则是通过其他方法通知给程序 (如: 回调函数等)

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

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

相关文章

2025年最新深度学习环境搭建:Win11+ cuDNN + CUDA + Pytorch +深度学习环境配置保姆级教程

本文目录 一、查看驱动版本1.1 查看显卡驱动1.2 显卡驱动和CUDA对应版本1.3 Pytorch和Python对应的版本1.4 Pytorch和CUDA对应的版本 二、安装CUDA三、安装cuDANN四、安装pytorch五、验证是否安装成功 一、查看驱动版本 1.1 查看显卡驱动 输入命令nvidia-smi可以查看对应的驱…

unity插件Excel转换Proto插件-ExcelToProtobufferTool

unity插件Excel转换Proto插件-ExcelToProtobufferTool **ExcelToProtobufTool 插件文档****1. 插件概述****2. 默认配置类&#xff1a;DefaultIProtoPathConfig****属性说明** **3. 自定义配置类****定义规则****示例代码** **4. 使用方式****4.1 默认路径****4.2 自定义路径**…

Web3 与数据隐私:如何让用户掌控个人信息

随着数字化时代的快速发展&#xff0c;互联网已经渗透到我们生活的方方面面&#xff0c;个人数据的收集与使用也变得越来越普遍。与此同时&#xff0c;数据隐私问题逐渐成为全球关注的焦点。传统的互联网平台通常将用户的数据存储在中心化的服务器上&#xff0c;这意味着平台拥…

SQL Server 建立每日自动log备份的维护计划

SQLServer数据库可以使用维护计划完成数据库的自动备份&#xff0c;下面以在SQL Server 2012为例说明具体配置方法。 1.启动SQL Server Management Studio&#xff0c;在【对象资源管理器】窗格中选择数据库实例&#xff0c;然后依次选择【管理】→【维护计划】选项&#xff0…

C++—21、C++ 中构造函数Constructors

一、什么是构造函数&#xff1f; 构造函数是一个特殊的方法&#xff0c;它在类每次实例化创建对象的时侯自动调用&#xff0c;用于初始化对象。 构造函数的名字必须与类名完全相同&#xff0c;并且没有返回类型&#xff0c;甚至连void也没有。 构造函数的目的是确保对象在创…

Tensor 基本操作1 unsqueeze, squeeze, softmax | PyTorch 深度学习实战

本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 目录 创建 Tensor常用操作unsqueezesqueezeSoftmax代码1代码2代码3 argmaxitem 创建 Tensor 使用 Torch 接口创建 Tensor import torch参考&#xff1a;https://pytorch.org/tutorials/beginn…

C# HTTP/HTTPS 请求测试小工具

这是一个使用 C# 语言开发的实用小工具&#xff0c;旨在帮助用户轻松测试 HTTP 和 HTTPS 请求。 该工具可以发送各种 HTTP 和 HTTPS 请求&#xff0c;包括但不限于 GET、POST、PUT、DELETE 等常见的请求类型。通过简洁明了的界面或命令行操作&#xff0c;用户可以方便地输入目…

Kyligence AI 数据智能体:首批亮相神州数码 DC·AI 生态创新中心!

近日&#xff0c;跬智信息&#xff08;Kyligence&#xff09;长期合作伙伴神州数码&#xff0c;其 DCAI 生态创新中心正式启幕。 作为首批生态伙伴&#xff0c;Kyligence AI 数据智能体也正式入驻&#xff0c;在这里首次亮相。 Kyligence 是国内最早推出 AI 用数产品的厂商&a…

Vue基础(2)

19、组件之间传递数据 组件与组件之间不是完全独立的&#xff0c;而是有交集的&#xff0c;那就是组件与组 件之间是可以传递数据的 传递数据的解决方案就是 props ComponentA.vue <template><!-- 使用ComponentB组件&#xff0c;并传递title属性 --><h3>…

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMXKeil, 创建一个SD卡读写的工程。 目录 一、SD卡要点速读 二、SDIO要点速读 三、SD卡座接线原理图 四、CubeMX新建工程 五、CubeMX 生成 SD卡的SDIO通信部分 六、Keil 编辑工程代码 七、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、SD卡 速读…

【深度学习】2.视觉问题与得分函数

计算机视觉任务 可以通过神经网络搜索是什么类别的动物。 图像实际就是含有数值的三维矩阵。 像素值从0-255可以表示亮度递增的参数。数字越大&#xff0c;像素点越亮。 最后的3表示三个颜色通道&#xff0c;常见的如JPG、RGB等。 现实场景容易发生各种遮蔽现象。 计算机判断…

JVM面试题解,垃圾回收之“分代回收理论”剖析

一、什么是分代回收 我们会把堆内存中的对象间隔一段时间做一次GC&#xff08;即垃圾回收&#xff09;&#xff0c;但是堆内存很大一块&#xff0c;内存布局分为新生代和老年代、其对象的特点不一样&#xff0c;所以回收的策略也应该各不相同 对于“刚出生”的新对象&#xf…

单片机-STM32 IIC通信(OLED屏幕)(十一)

一、屏幕的分类 1、LED屏幕&#xff1a; 由无数个发光的LED灯珠按照一定的顺序排列而成&#xff0c;当需要显示内容的时候&#xff0c;点亮相关的LED灯即可&#xff0c;市场占有率很高&#xff0c;主要是用于户外&#xff0c;广告屏幕&#xff0c;成本低。 LED屏是一种用发光…

Windows cmd常用命令

文章目录 Windows cmd常用命令一、引言二、文件和目录操作1、查看和切换目录2、文件和目录的创建与删除 三、系统信息与网络配置1、系统信息2、网络配置 四、使用示例五、总结 Windows cmd常用命令 一、引言 Windows 命令提示符&#xff08;cmd&#xff09;是一个强大的工具&a…

snippets router pinia axios mock

文章目录 补充VS Code 代码片段注册自定义组件vue routerpinia删除vite创建项目时默认的文件axiosmock3.0.x版本的 viteMockServe 补充 为文章做补充&#xff1a;https://blog.csdn.net/yavlgloss/article/details/140063387 VS Code 代码片段 为当前项目创建 Snippets {&quo…

神经网络基础 | 给定条件下推导对应的卷积层参数

神经网络基础 | 给定条件下推导对应的卷积层参数 按照 PyTorch 文档中 给定的设置&#xff1a; H o u t ⌊ H i n 2 padding [ 0 ] − dilation [ 0 ] ( kernel_size [ 0 ] − 1 ) − 1 stride [ 0 ] 1 ⌋ H_{out} \left\lfloor\frac{H_{in} 2 \times \text{padding}[0]…

欧拉(Euler 22.03)安装ProxySQL

下载离线安装包 proxysql-2.0.8-1-centos7.x86_64.rpm 链接: https://pan.baidu.com/s/1R-SJiVUEu24oNnPFlm9wRw 提取码: sa2w离线安装proxysql yum localinstall -y proxysql-2.0.8-1-centos7.x86_64.rpm 启动proxysql并检查状态 systemctl start proxysql 启动proxysql syste…

Sharding-JDBC 5.4.1+SpringBoot3.4.1+MySQL8.4.1 使用案例

最近在升级 SpringBoot 项目&#xff0c;原版本是 2.7.16&#xff0c;要升级到 3.4.0 &#xff0c;JDK 版本要从 JDK8 升级 JDK21&#xff0c;原项目中使用了 Sharding-JDBC&#xff0c;版本 4.0.0-RC1&#xff0c;在升级 SpringBoot 版本到 3.4.0 之后&#xff0c;服务启动失败…

WPS计算机二级•幻灯片的基础操作

听说这是目录哦 PPT的正确制作步骤&#x1f6e3;️认识PPT界面布局&#x1f3dc;️PPT基础操作 快捷键&#x1f3de;️制作PPT时 常用的快捷技巧&#x1f3d9;️快速替换PPT的 文本字体&#x1f303;快速替换PPT 指定文本内容&#x1f305;能量站&#x1f61a; PPT的正确制作步…

easyexcel读取写入excel easyexceldemo

1.新建springboot项目 2.添加pom依赖 <name>excel</name> <description>excelspringboot例子</description><parent> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId&…