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

五种I/O模型

目录

  • 1、阻塞IO模型
  • 2、非阻塞IO模型
  • 3、IO多路复用模型
  • 4、信号驱动IO模型
  • 5、异步IO模型
  • 总结

  1. blockingIO - 阻塞IO
  2. nonblockingIO - 非阻塞IO
  3. IOmultiplexing - IO多路复用
  4. signaldrivenIO - 信号驱动IO
  5. asynchronousIO - 异步IO

5种模型的前4种模型为同步IO,只有异步IO模型是异步IO操作

首先,我们知道对于一个网络输入操作通常包括两个不同阶段:

第一阶段:等待网络数据到达网卡→读取到内核缓冲区(数据准备好)

第二阶段:从内核缓冲区复制数据到进程缓冲区(复制数据了)

这很显然是两个操作,所以我们重点关注以下2点操作:

A、等待数据读取到内核缓冲区(数据准备)

B、复制内核缓冲区数据到进程缓冲区(数据复制)

1、阻塞IO模型

进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。

调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的去检查这个函数有没有返回,必须等这个函数返回才能进行下一步动作。

即:A阻塞,B阻塞

举例:

你准备去书店买书,但老板不在,留了电话

你打电话问老板:有没有《三体》卖?

老板查了一下说:书店里没有《三体》,我打个电话让供应商送货,你等一下

然后你就一直在书店里等着,不吃饭,不睡觉(进入A阶段,等待数据,陷入了IO阻塞)

过了一段时间,供应商把书送到书店

老板打电话给你:书已经到了,你有空吗?等你有空,我才当面把书交给你(进入B阶段,数据复制,阻塞住了)

交易完成

2、非阻塞IO模型

进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞,但会一直轮询内核缓冲区数据准备好了没。进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。

非阻塞等待,每隔一段时间就去检测IO事件是否就绪。没有就绪就可以做其他事。非阻塞I/O执行系统调用总是立即返回,不管时间是否已经发生,若时间没有发生,则返回-1,此时可以根据errno区分这两种情况,对于accept,recv和send,事件未发生时,errno通常被设置成eagain。

即:A不阻塞,B阻塞

举例:

你准备去书店买书,但老板不在,留了电话

你打电话问老板:有没有《三体》卖?

老板查了一下说:书店里没有《三体》,我打个电话让供应商送货,你先回家去吧,过几天再来问(进入A阶段,等待数据,但非阻塞)

想象:你回到家,该吃就吃,该喝就喝,隔了1周后才打电话问老板书到了没?(非阻塞,继续做别的事情)

但一般编程,都会设置轮询IO,即:

实际:你回到家,循环不停地打电话给老板,我的书到了没?(陷入事实上的轮询IO阻塞,相当于死循环,即使属于非阻塞模型)

过了1个小时,老板说:书已经到了,你有空吗?等你有空,我才当面把书交给你(进入B阶段,数据复制,阻塞住了)

交易完成

3、IO多路复用模型

多个进程的IO可以注册到一个复用器(select)上,然后用一个进程调用该复用器(select)。 复用器(select)会监听所有注册进来的IO。如果复用器(select)所监听的IO在内核缓冲区都没有可读数据,复用器(select)调用进程会被阻塞;而当任一IO在内核缓冲区中有可数据时,复用器(select)调用就会返回。之后复用器(select)通知注册进程来再次发起读取IO,读取内核中准备好的数据。

linux用select/poll函数实现IO复用模型,这两个函数也会使进程阻塞,但是和阻塞IO所不同的是这两个函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检测。知道有数据可读或可写时,才真正调用IO操作函数。

即:A不阻塞,B阻塞

举例:

对于书店老板来说,他对接的是多个客人。你,张三,李四都打电话给老板,要买书

你买《三体》,张三买《鲁迅》,李四买《史记》,然后最坏的情况,3本书老板都没有

老板说:我打个电话让供应商送货,你们先别一直打电话,书到了我再打电话让你们过来取

实际:你,张三,李四挂了电话,就去吃饭睡觉,做自己的事了(进入A阶段,等待数据,但非阻塞)

老板一直等不到供应商来送货,但自己需要一直等待着(陷入事实上的select/poll/epoll阻塞)

此时供应商送来一本书,但老板不知道属于谁,得遍历一边购书单,发现是你的书

老板打电话给你:书已经到了,你有空吗?等你有空,我才当面把书交给你(进入B阶段,数据复制,阻塞住了)

交易完成

4、信号驱动IO模型

当进程发起一个IO操作,会向内核注册一个信号处理函数 ,然后进程返回;当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用IO读取数据

linux用套接口进行信号驱动IO,安装一个信号处理函数,进程继续运行并不阻塞,当IO时间就绪,进程收到SIGIO信号。然后处理IO事件。

即:A不阻塞,B阻塞

举例:

你准备去书店买书,但老板不在,留了电话

你打电话问老板:有没有《三体》卖?

老板查了一下说:书店里没有《三体》

然后你说:我给你留个收货地址。如果书到了,你打电话给我,我会让别人在这个地址接收你的书

然后你就回家去了,该干嘛干嘛(进入A阶段,等待数据,但留了回调函数,非阻塞)

老板打电话给你:书已经到了,让你的人准备好,我才当面把书交给你的人(进入B阶段,数据复制,阻塞住了)

交易完成

5、异步IO模型

当进程发起一个IO操作,进程立即返回,但也不返回结果;内核把整个IO处理完后,会通知进程结果。如果IO操作成功则进程直接获取到数据。所谓的通知进程结果,是指:包含将数据从内核复制到应该进程的缓冲区,完成后通知应用进程,也就是说,已经完成了A B 2个步骤了,才通知请求进程,此时请求进程直接获取到数据,根本不会阻塞,即所谓的异步。

linux中,可以调用aio_read函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。

即:A不阻塞,B不阻塞

你准备去书店买书,但老板不在,留了电话

你打电话问老板:有没有《三体》卖?

老板查了一下说:书店里没有《三体》,你留个地址,书到了我会把书送到你家去

然后你就回家去了,该干嘛干嘛(进入A阶段,等待数据,非阻塞)

老板接收到供应商的书,把书放到你家楼下,而此时你在家睡觉(进入B阶段,数据复制,非阻塞)

老板打电话给你:书已经到了,在你家楼下,自己去拿吧

交易完成

总结

根据上面所说的IO操作的两个阶段,可以把上面的I/O模型进行如下归类:

阻塞IO:在两个阶段上面都是阻塞的,A阶段阻塞,B阶段还是阻塞
非阻塞IO:在A不阻塞(但陷入事实上的轮询IO阻塞),B阶段还是阻塞的
IO复用:A阶段不阻塞(陷入事实上的select/poll/epoll阻塞),B阶段还是阻塞的
信号IO:A阶段不阻塞,当信号通知程序数据准备完毕,B阶段还是阻塞的
异步IO:A阶段不阻塞,B阶段不阻塞

现在,我们可以看到,前4种IO模型的B阶段:数据复制阶段都是阻塞,也就是按POSIX标准来说的同步IO,最后1种异步IO模型,才是按POSIX标准来说的异步IO。

同步一般指主动请求并等待I/O操作完毕的方式,I/O操作未完成前,会导致应用进程挂起

而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知(异步的特点就是通知),这可以使进程在数据读写时也不阻塞

阻塞或者非阻塞I/O主要是指I/O操作第一阶段的完成方式(进程访问的数据如果尚未就绪),即数据还未准备好的时候,应用进程的表现

如果这里进程挂起,则为阻塞I/O,否则为非阻塞I/O,主要是描述进程在数据未准备好时的状态,根据进程等待数据时的状态来判断

阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式:

说白了就是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待

而非阻塞方式下,读取或者写入函数会立即返回一个状态值

相关文章:

五种I/O模型

目录 1、阻塞IO模型2、非阻塞IO模型3、IO多路复用模型4、信号驱动IO模型5、异步IO模型总结 blockingIO - 阻塞IOnonblockingIO - 非阻塞IOIOmultiplexing - IO多路复用signaldrivenIO - 信号驱动IOasynchronousIO - 异步IO 5种模型的前4种模型为同步IO,只有异步IO模…...

用nativescript开发ios程序常用命令?

NativeScript是一个用于跨平台移动应用程序开发的开源框架,允许您使用JavaScript或TypeScript构建原生iOS和Android应用程序。以下是一些常用的NativeScript命令,用于开发iOS应用程序: 1、创建新NativeScript项目: tns create m…...

6.Tensors For Beginners-What are Convector

Covectors (协向量) What‘s a covector Covectors are “basically” Row Vectors 在一定程度上,可认为 协向量 基本上就像 行向量。 但不能简单地认为 这就是列向量进行转置! 行向量 和 列向量 是根本不同类型的对象。 …...

Linux多线程网络通信

思路:主线程(只有一个)建立连接,就创建子线程。子线程开始通信。 共享资源:全局数据区,堆区,内核区描述符。 线程同步不同步需要取决于线程对共享资源区的数据的操作,如果是只读就不…...

矩阵的c++实现(2)

上一次我们了解了矩阵的运算和如何使用矩阵解决斐波那契数列&#xff0c;这一次我们多看看例题&#xff0c;了解什么情况下用矩阵比较合适。 先看例题 1.洛谷P1939 【模板】矩阵加速&#xff08;数列&#xff09; 模板题应该很简单。 补&#xff1a;1<n<10^9 10^9肯定…...

RPC 框架之Thrift入门(一)

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…...

【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )

文章目录 一、后置运算符重载1、前置运算符重载 与 后置运算符重载 的区别2、后置运算符重载添加 int 占位参数 上 2 2 2 篇博客 【C】运算符重载 ④ ( 一元运算符重载 | 使用 全局函数 实现 前置 自增运算符重载 | 使用 全局函数 实现 前置 - - 自减运算符重载 )【C】运算符…...

538. 把二叉搜索树转换为累加树

题目描述 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下&#xff0c;二叉搜索树满足下列约束…...

java8日期时间工具类

【README】 1&#xff09;本文总结了java8中日期时间常用工具方法&#xff1b;包括&#xff1a; 日期时间对象格式化为字符串&#xff1b;日期时间字符串解析为日期时间对象&#xff1b;日期时间对象转换&#xff1b; 转换过程中&#xff0c;需要注意的是&#xff1a; Instan…...

算法-动态规划/trie树-单词拆分

算法-动态规划/trie树-单词拆分 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/word-break/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 动态规划 2.1 解题思路 dp[i]表示[0, i)字符串可否构建那么dp[i]可构建的条件是&…...

React框架核心原理

一、整体架构 三大核心库与对应的组件 history -> react-router -> react-router-dom react-router 可视为react-router-dom 的核心&#xff0c;里面封装了<Router>&#xff0c;<Route>&#xff0c;<Switch>等核心组件,实现了从路由的改变到组件的更新…...

python-pytorch 利用pytorch对堆叠自编码器进行训练和验证

利用pytorch对堆叠自编码器进行训练和验证 一、数据生成二、定义自编码器模型三、训练函数四、训练堆叠自编码器五、将已训练的自编码器级联六、微调整个堆叠自编码器 一、数据生成 随机生成一些数据来模拟训练和验证数据集&#xff1a; import torch# 随机生成数据 n_sample…...

制作 3 档可调灯程序编写

PWM 0~255 可以将数据映射到0 75 150 225 尽可能均匀电压间隔...

源码分享-M3U8数据流ts的AES-128解密并合并---GoLang实现

之前使用C语言实现了一次&#xff0c;见M3U8数据流ts的AES-128解密并合并。 学习了Go语言后&#xff0c;又用Go重新实现了一遍。源码如下&#xff0c;无第三方库依赖。 package mainimport ("crypto/aes""crypto/cipher""encoding/binary"&quo…...

CSDN Q: “这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗?“

这是 CSDN上的一个问题 这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗&#xff0c;还是说得用上定时器和中断函数#include <regx52.h> 我个人认为: 效果上来说, 是的! 码以 以Time / 100-Time 调 Duty, 而 for i loop成 Period, 加上延时, 实现了 PWM周期, 虽然…...

Linux系统编程系列之线程池

Linux系统编程系列&#xff08;16篇管饱&#xff0c;吃货都投降了&#xff01;&#xff09; 1、Linux系统编程系列之进程基础 2、Linux系统编程系列之进程间通信(IPC)-信号 3、Linux系统编程系列之进程间通信(IPC)-管道 4、Linux系统编程系列之进程间通信-IPC对象 5、Linux系统…...

Linux CentOS7 vim多文件与多窗口操作

窗口是可视化的分割区域。Windows中窗口的概念与linux中基本相同。连接xshell就是在Windows中新建一个窗口。而vim打开一个文件默认创建一个窗口。同时&#xff0c;Vim打开一个文件也就会建立一个缓冲区&#xff0c;打开多个文件就会创建多个缓冲区。 本文讨论vim中打开多个文…...

SPI 通信协议

1. SPI通信 1. 什么是SPI通信协议 2. SPI的通信过程 在一开始会先把发送缓冲器的数据&#xff08;8位&#xff09;。一次性放到移位寄存器里。 移位寄存器会一位一位发送出去。但是要先放到锁存器里。然后从机来读取。从机的过程也一样。当移位寄存器的数据全部发送完。其实…...

【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

5个适合初学者的初级网络安全工作,网络安全就业必看

前言 网络安全涉及保护计算机系统、网络和数据免受未经授权的访问、破坏和盗窃 - 防止数字活动和数据访问的中断 - 同时也保护用户的资产和隐私。鉴于公共事业、医疗保健、金融以及联邦政府等行业的网络犯罪攻击不断升级&#xff0c;对网络专业人员的需求很高&#xff0c;这并…...

TscanCode静态代码扫描工具原理与实践

嵌入式静态代码扫描工具TscanCode深度解析1. 静态代码分析技术概述1.1 静态代码扫描原理静态代码扫描是一种在不实际执行程序的情况下&#xff0c;通过词法分析、语法分析、控制流和数据流分析等技术对源代码进行检测的方法。这种技术能够有效识别代码中潜在的错误和缺陷&#…...

Arduino激光360°扫描库:VL53L0X+28BYJ-48低成本建图方案

1. 项目概述LaserToMap360 是一个面向嵌入式空间感知应用的轻量级 Arduino 库&#xff0c;专为构建低成本、可复现的 360 激光测距扫描系统而设计。其核心目标并非替代专业 SLAM 系统&#xff0c;而是提供一种工程上可快速验证、硬件上可即插即用、数据上可直接对接上位机可视化…...

Qt串口通信实战:用QSerialPort从零搭建一个串口调试助手(附完整源码)

Qt串口通信实战&#xff1a;从零构建工业级调试助手 在嵌入式开发和工业控制领域&#xff0c;串口通信作为最基础也最可靠的通信方式之一&#xff0c;至今仍发挥着不可替代的作用。无论是单片机与上位机的数据交换&#xff0c;还是工业设备的参数配置&#xff0c;一个稳定高效的…...

46535

4675328...

小白程序员必看:收藏这份上下文工程指南,轻松玩转大模型!

本文深入浅出地介绍了上下文工程在大语言模型中的重要性&#xff0c;阐述了指令、示例、知识、记忆、工具和安全护栏等六种上下文类型。文章详细解析了上下文工程的四个基本阶段&#xff1a;撰写上下文、选择上下文、压缩上下文和隔离上下文&#xff0c;并强调了上下文窗口的作…...

企业级流程建模前端架构:基于Vite+Vue3的低代码解决方案

企业级流程建模前端架构&#xff1a;基于ViteVue3的低代码解决方案 【免费下载链接】vite-vue-bpmn-process 基于 Vite TypeScript Vue3 NaiveUI Bpmn.js 的流程编辑器&#xff08;前端部分&#xff09;。支持高度自定义&#x1f680;&#x1f680;&#x1f680;。Vue 2 版本…...

洛谷 P1833:樱花 ← 混合背包(01 + 完全 + 多重)

【题目来源】 https://www.luogu.com.cn/problem/P1833 【题目描述】 爱与愁大神后院里种了 n 棵樱花树&#xff0c;每棵都有美学值 Ci(0<Ci≤200)。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸&#xff0c;他懂得如何欣赏樱花&#xff1a;一种樱花树看一遍…...

别再只懂概念了!用JSEncrypt库5分钟搞定前端RSA密码加密实战

前端RSA加密实战&#xff1a;用JSEncrypt保护用户密码传输安全 1. 为什么前端需要加密&#xff1f; 在Web应用开发中&#xff0c;用户登录是最基础也最敏感的操作之一。传统表单提交直接将密码以明文形式发送到服务器&#xff0c;这在网络传输过程中存在被截获的风险。即使使…...

企业高效知识体系:8大核心特征+可落地搭建框架,告别知识散乱

对于企业而言&#xff0c;知识从来不是“文件堆”&#xff0c;而是能支撑业务、培养新人、规避风险的核心资产。很多企业陷入“文档满天飞、新人没人带、老员工离职带跑经验”的困境&#xff0c;本质是没有搭建起高效、完整的知识体系。今天就一次性讲透&#xff1a;一个能真正…...

AtlasOS系统性能优化指南:从诊断到维护的全流程解决方案

AtlasOS系统性能优化指南&#xff1a;从诊断到维护的全流程解决方案 【免费下载链接】Atlas &#x1f680; An open and lightweight modification to Windows, designed to optimize performance, privacy and security. 项目地址: https://gitcode.com/GitHub_Trending/atl…...