当前位置: 首页 > 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;这并…...

Kafka核心原理

1、Topic的分片和副本机制 分片作用&#xff1a; 解决单台节点容量有限的问题&#xff0c;节点多&#xff0c;效率提升&#xff0c;吞吐量提升。通过分片&#xff0c;将一个大的容器分解为多个小的容器&#xff0c;分布在不同的节点上&#xff0c;从而实现分布式存储。 分片…...

探秘前后端开发世界:猫头虎带你穿梭编程的繁忙街区,解锁全栈之路

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

洛谷_分支循环

p2433 问题 5 甲列火车长 260 米&#xff0c;每秒行 12 米&#xff1b;乙列火车长220 米&#xff0c;每秒行 20 米&#xff0c;两车相向而行&#xff0c;从两车车头相遇时开始计时&#xff0c;多长时间后两车车尾相离&#xff1f;已知答案是整数。 计算方式&#xff1a;两车车…...

MySQL数据库入门到精通——进阶篇(3)

黑马程序员 MySQL数据库入门到精通——进阶篇&#xff08;3&#xff09; 1. 锁1.1 锁-介绍1.2 锁-全局锁1.3 锁-表级锁1.3.1 表级锁-表锁1.3.2 表级锁元数据锁( meta data lock&#xff0c;MDL)1.3.3 表级锁-意向锁1.3.4 表级锁意向锁测试 1.4 锁-行级锁1.4.1 行级锁-行锁1.4.2…...

Mind Map:大语言模型中的知识图谱提示激发思维图10.1+10.2

知识图谱提示激发思维图 摘要介绍相关工作方法第一步&#xff1a;证据图挖掘第二步&#xff1a;证据图聚合第三步&#xff1a;LLM Mind Map推理 实验实验设置医学问答长对话问题使用KG的部分知识生成深入分析 总结 摘要 LLM通常在吸收新知识的能力、generation of hallucinati…...

[引擎开发] 杂谈ue4中的Vulkan

接触Vulkan大概也有大半年&#xff0c;概述一下自己这段时间了解到的东西。本文实际上是杂谈性质而非综述性质&#xff0c;带有严重的主观认知&#xff0c;因此并没有那么严谨。 使用Vulkan会带来什么呢&#xff1f;简单来说就是对底层更好的控制。这意味着我们能够有更多的手段…...

docker--redis容器部署及地理空间API的使用示例-II

文章目录 Redis 地理位置类型API命令操作示例JAVA使用示例导入依赖RedisTemplate 操作GeoData示例CityInfo实体类Geo操作接口类Geo操作接口实现类SpringBoot测试类RedissonClient 操作GeoData示例docker–redis容器部署及与SpringBoot整合 docker–redis容器部署及地理空间API的…...

Vue中如何进行文件浏览与文件管理

Vue中的文件浏览与文件管理 文件浏览与文件管理是许多Web应用程序中常见的功能之一。在Vue.js中&#xff0c;您可以轻松地实现文件浏览和管理功能&#xff0c;使您的应用程序更具交互性和可用性。本文将向您展示如何使用Vue.js构建文件浏览器和文件管理功能&#xff0c;以及如…...

jenkins利用插件Active Choices Plug-in达到联动显示或隐藏参数,且参数值可修改

1. 添加组件 Active Choices Plug-in 如jenkins无法联网&#xff0c;可在以下两个地址中下载插件&#xff0c;然后放到/home/jenkins/.jenkins/plugin下面重启jenkins即可 Active Choices Active Choices | Jenkins plugin 2. 效果如下&#xff1a; sharding为空时&#xf…...

香蕉叶病害数据集

1.数据集 第一个文件夹为数据增强&#xff08;旋转平移裁剪等操作&#xff09;后的数据集 第二个文件夹为原始数据集 2.原始数据集 Cordana文件夹&#xff08;162张照片&#xff09; healthy文件夹&#xff08;129张&#xff09; Pestalotiopsis文件夹&#xff08;173张照片&…...

建站大师排名表2021/广东公司搜索seo哪家强

说明 适合 vue2.0版本的官方链接如下&#xff1a;​​​​​​Vue I18nVue I18n 是 Vue.js 的国际化插件https://kazupon.github.io/vue-i18n/zh/ 适合vue3.0 版本的官方链接如下&#xff08;目前该文档只有英文和日语&#xff0c;中文翻译需要借助浏览器-2021-12-11 08:53&a…...

住房和城乡建设局网站/杭州关键词自动排名

路由 hash模式&#xff08;网址上带#号&#xff09;hlstory模式&#xff08;网址上没有#号&#xff0c;正式上线需要服务端支持&#xff09; 准备登陆组件并添加路由 在 src/views 新建一个 Login/indexvue 页面&#xff0c;用作陆页面在router 文件里去写路由规则在app.vue …...

老外做汉字网站/营销模式有哪些 新型

statspack 是一个很重要的工具, 这是我们重点要知道的在这章 每天一上班就要看一下 alert log 文件, 可以通过/ORA找, 这是vi的知识&#xff0c;所有的ORACLE错误都是以ORA开头的 日志文件有的时候需要将里边内容拷贝走&#xff0c;清空。 cat /dev/null > alert_pitts.log …...

网站设置搜索框是什么知识点/河南制作网站

在和数据打交道的过程中&#xff0c;总会遇到误删除数据的情况,在没有备份和binlog的情况下&#xff0c;如何恢复呢&#xff1f;本文介绍一个工具Percona Data Recovery Tool for InnoDB使用 该工具的 注意事项:1 The tools work only for InnoDB/XtraDB tables, and will not …...

校园网站建设特色/竞价推广怎么样

原文&#xff1a;http://blog.csdn.net/xhyzfl/article/details/6828943 最近虚拟机在启动Linux系统时&#xff0c;总是停在starting sendmail上很长时间&#xff0c;接下来的starting sm-client也是异常的慢。后来查资料&#xff0c;才知道原来是和更改hostname有关。回想一下…...

wordpress做的网站吗/全国推广优化网站

类的初始化由执行类中静态代码块的初始化和类中声明的静态域的初始化两部分组成接口的初始化由接口中声明的域(常量)的初始化组成初始化的时机类或接口T在以下任意情况发生之前会立即进行初始化:T是一个类并且创建了一个T的实列T中声明的一个静态方法被调用T中声明的一个静态域…...