IO - 同步,异步,阻塞,非阻塞
同步synchronous IO和异步asynchronous IO阻塞blocking IO和非阻塞non-blockingIO分别是什么到底有什么区别这个问题其实不同的人给出的答案都可能不同比如wiki就认为asynchronous IO和non-blocking IO是一个东西。这其实是因为不同的人的知识背景不同并且在讨论这个问题的时候上下文(context)也不相同。所以为了更好的回答这个问题我先限定一下本文的上下文。本文讨论的背景是Linux环境下的network IO。本文最重要的参考文献是Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”6.2节“I/O Models ”Stevens在这节中详细说明了各种IO的特点和区别如果英文够好的话推荐直接阅读。Stevens的文风是有名的深入浅出所以不用担心看不懂。本文中的流程图也是截取自参考文献。Stevens在文章中一共比较了五种IO Modelblocking IOnonblocking IOIO multiplexingsignal driven IOasynchronous IO由于signal driven IO在实际中并不常用所以我这只提及剩下的四种IO Model。再说一下IO发生时涉及的对象和步骤。对于一个network IO (这里我们以read举例)它会涉及到两个系统对象一个是调用这个IO的process (or thread)另一个就是系统内核(kernel)。当一个read操作发生时它会经历两个阶段1 等待数据准备 (Waiting for the data to be ready)2 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)记住这两点很重要因为这些IO Model的区别就是在两个阶段上各有不同的情况。blocking IO在linux中默认情况下所有的socket都是blocking一个典型的读操作流程大概是这样当用户进程调用了recvfrom这个系统调用kernel就开始了IO的第一个阶段准备数据。对于network io来说很多时候数据在一开始还没有到达比如还没有收到一个完整的UDP包这个时候kernel就要等待足够的数据到来。而在用户进程这边整个进程会被阻塞。当kernel一直等到数据准备好了它就会将数据从kernel中拷贝到用户内存然后kernel返回结果用户进程才解除block的状态重新运行起来。所以blocking IO的特点就是在IO执行的两个阶段都被block了。non-blocking IOlinux下可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时流程是这个样子从图中可以看出当用户进程发出read操作时如果kernel中的数据还没有准备好那么它并不会block用户进程而是立刻返回一个error。从用户进程角度讲 它发起一个read操作后并不需要等待而是马上就得到了一个结果。用户进程判断结果是一个error时它就知道数据还没有准备好于是它可以再次发送read操作。一旦kernel中的数据准备好了并且又再次收到了用户进程的system call那么它马上就将数据拷贝到了用户内存然后返回。所以用户进程其实是需要不断的主动询问kernel数据好了没有。IO multiplexingIO multiplexing这个词可能有点陌生但是如果我说selectepoll大概就都能明白了。有些地方也称这种IO方式为event driven IO。我们都知道select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket当某个socket有数据到达了就通知用户进程。它的流程如图当用户进程调用了select那么整个进程会被block而同时kernel会“监视”所有select负责的socket当任何一个socket中的数据准备好了select就会返回。这个时候用户进程再调用read操作将数据从kernel拷贝到用户进程。这个图和blocking IO的图其实并没有太大的不同事实上还更差一些。因为这里需要使用两个system call (select 和 recvfrom)而blocking IO只调用了一个system call (recvfrom)。但是用select的优势在于它可以同时处理多个connection。多说一句。所以如果处理的连接数不是很高的话使用select/epoll的web server不一定比使用multi-threading blocking IO的web server性能更好可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快而是在于能处理更多的连接。在IO multiplexing Model中实际中对于每一个socket一般都设置成为non-blocking但是如上图所示整个用户的process其实是一直被block的。只不过process是被select这个函数block而不是被socket IO给block。Asynchronous I/Olinux下的asynchronous IO其实用得很少。先看一下它的流程用户进程发起read操作之后立刻就可以开始去做其它的事。而另一方面从kernel的角度当它受到一个asynchronous read之后首先它会立刻返回所以不会对用户进程产生任何block。然后kernel会等待数据准备完成然后将数据拷贝到用户内存当这一切都完成之后kernel会给用户进程发送一个signal告诉它read操作完成了。到目前为止已经将四个IO Model都介绍完了。现在回过头来回答最初的那几个问题blocking和non-blocking的区别在哪synchronous IO和asynchronous IO的区别在哪。先回答最简单的这个blocking vs non-blocking。前面的介绍中其实已经很明确的说明了这两者的区别。调用blocking IO会一直block住对应的进程直到操作完成而non-blocking IO在kernel还准备数据的情况下会立刻返回。在说明synchronous IO和asynchronous IO的区别之前需要先给出两者的定义。Stevens给出的定义其实是POSIX的定义是这样子的A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;An asynchronous I/O operation does not cause the requesting process to be blocked;两者的区别就在于synchronous IO做”IO operation”的时候会将process阻塞。按照这个定义之前所述的blocking IOnon-blocking IOIO multiplexing都属于synchronous IO。有人可能会说non-blocking IO并没有被block啊。这里有个非常“狡猾”的地方定义中所指的”IO operation”是指真实的IO操作就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候如果kernel的数据没有准备好这时候不会block进程。但是当kernel中数据准备好的时候recvfrom会将数据从kernel拷贝到用户内存中这个时候进程是被block了在这段时间内进程是被block的。而asynchronous IO则不一样当进程发起IO 操作之后就直接返回再也不理睬了直到kernel发送一个信号告诉进程说IO完成。在这整个过程中进程完全没有被block。各个IO Model的比较如图所示经过上面的介绍会发现non-blocking IO和asynchronous IO的区别还是很明显的。在non-blocking IO中虽然进程大部分时间都不会被block但是它仍然要求进程去主动的check并且当数据准备完成以后也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人kernel完成然后他人做完后发信号通知。在此期间用户进程不需要去检查IO操作的状态也不需要主动的去拷贝数据。最后再举几个不是很恰当的例子来说明这四个IO Model:有ABCD四个人在钓鱼A用的是最老式的鱼竿所以呢得一直守着等到鱼上钩了再拉杆B的鱼竿有个功能能够显示是否有鱼上钩所以呢B就和旁边的MM聊天隔会再看看有没有鱼上钩有的话就迅速拉杆C用的鱼竿和B差不多但他想了一个好办法就是同时放好几根鱼竿然后守在旁边一旦有显示说鱼上钩了它就将对应的鱼竿拉起来D是个有钱人干脆雇了一个人帮他钓鱼一旦那个人把鱼钓上来了就给D发个短信。————————————————原文链接https://blog.csdn.net/historyasamirror/article/details/5778378

相关新闻

Unity游戏开发从入门到精通:构建技能金字塔与实战路径

Unity游戏开发从入门到精通:构建技能金字塔与实战路径

1. 项目概述:为什么Unity值得你投入时间?如果你对游戏开发、交互式内容创作,或者仅仅是“创造一个属于自己的虚拟世界”抱有热情,那么Unity引擎几乎是你绕不开的一个名字。它早已不是那个只被独立开发者用来制作2D小游戏的工具了。…

2026/10/19 12:55:20 阅读更多 →
JavaSE:基础入门(一)

JavaSE:基础入门(一)

1、关键字 被java赋予特定含义的单词,特点:全部都是小写 以下是java的关键字列表,先了解下即可,其中void就是关键字,而 Void就不是关键字,只是一个占位符的类 访问控制 private protected public类,方法和变量修…

2026/10/20 1:13:47 阅读更多 →
Godot 4 AnimatedSprite2D 实战:让待机与移动动画自动切换

Godot 4 AnimatedSprite2D 实战:让待机与移动动画自动切换

Godot 4 AnimatedSprite2D 实战:让待机与移动动画自动切换角色已经能移动,但如果始终显示同一张图片,游戏仍会显得像在拖动贴纸。AnimatedSprite2D 可以用一个 SpriteFrames 资源管理多组逐帧动画,再根据角色的真实速度切换 idle …

2026/10/20 1:13:51 阅读更多 →

最新新闻

神经网络边权更新:从浮点精度到硬件协同的工程实践

神经网络边权更新:从浮点精度到硬件协同的工程实践

1. 这不是“调参”,而是神经网络的“肌肉记忆”形成过程很多人第一次看到反向传播公式时,下意识觉得:“哦,就是按链式法则求个导,然后用学习率乘一下更新权重。”——这就像说“跑步就是抬腿、迈步、落地”&#xff0c…

2026/10/20 4:27:40 阅读更多 →
SRGAN原理与实战:超分辨率生成对抗网络详解

SRGAN原理与实战:超分辨率生成对抗网络详解

简介:本资源是基于SRGAN(生成对抗网络)的图像超分辨率完整复现项目,面向深度学习初学者与计算机视觉方向研究者,聚焦解决大倍率(4)超分中高频纹理丢失、感知质量差的核心难题。项目实现了论文提…

2026/10/20 4:27:40 阅读更多 →
TCP协议深度实训:银行前置机通信的三道安检门与二进制报文解析

TCP协议深度实训:银行前置机通信的三道安检门与二进制报文解析

1. 这不是“银行系统”,而是一次面向真实金融场景的TCP协议深度实训很多人看到“网络银行”四个字,第一反应是点开一个网页输账号密码——但这次我们要做的,恰恰是把浏览器、HTTPS、前端框架这些“遮羞布”全撕掉,直接蹲在TCP连接…

2026/10/20 4:27:40 阅读更多 →
AutoRemesher 网格修复:把破面高模重网格成干净四边形

AutoRemesher 网格修复:把破面高模重网格成干净四边形

AutoRemesher 网格修复:把破面高模重网格成干净四边形 【免费下载链接】autoremesher Automatic quad remeshing tool 项目地址: https://gitcode.com/GitHub_Trending/au/autoremesher 扫描仪吐出的高模又密又破:几百万张碎三角面,边…

2026/10/20 4:27:40 阅读更多 →
WorkBuddy_WorkBuddy界面布局指南18_移动端App界面布局

WorkBuddy_WorkBuddy界面布局指南18_移动端App界面布局

移动端App界面布局 摘要 本文围绕移动端App界面布局展开讨论,重点分析手机端与桌面端在布局上的核心差异,并针对"云端工作"与"连接电脑"双模式场景,给出界面切换的设计思路与可运行的代码实现。文章涵盖视口与响应式基础…

2026/10/20 4:27:40 阅读更多 →
Qt新建工程全攻略:从环境配置到构建调试一步到位

Qt新建工程全攻略:从环境配置到构建调试一步到位

最近有朋友问我:Qt 到底怎么新建工程?他说自己把 Qt Creator 装好了,结果打开软件,面对一堆模板和选项完全不知道该点哪里。这个问题看起来基础,但我在带新人时发现,能在这一步顺畅走完、并且真正理解每个选…

2026/10/20 4:26:40 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →