也谈阻塞、非阻塞、同步、异步

简介: 最近在招聘中,发现不少人对BIO、NIO、AIO等理解非常模糊,觉得有必要写文章来纠正下很多人的误解。

最近在招聘中,发现不少人对BIO、NIO、AIO等理解非常模糊,觉得有必要写文章来纠正下很多人的误解。
在谈这些之前,非常有必要先介绍下Unix 5种IO模型:
阻塞:
阻塞是最常用的IO模型,默认情况下所有的文件操作都是阻塞的。以套接字编程为例。在进程空间中调用recvfrom,其系统调用直到数据报文到达且被拷贝到应用程序进程的缓存区(或者发生错误)后才返回,期间一直在等待。进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。有一张很经典的图:
阻塞IO模型
非阻塞:
调用recvfrom从应用层到内核的过程中,如果该缓冲区没有数据的话,则直接返回一个EWOULDBLOCK的错误,一般会轮询的进行检查状态,看内核空间有没有数据来。直到有数据,最后完成拷贝。如下图:
非阻塞IO模型
IO多路复用:
Linux系统提供的select/poll/epoll,进程将一个或者多个FD(文件描述符)传递给一个或者多个poll/select系统调用,阻塞在select。select和poll可以帮助侦听很多的FD是否准备就绪。但是,select和poll是顺序扫描去检查FD的就绪状态,效率比较低,而且支持的FD数量有限(没记错的话,默认好像是1024还是2048,具体记不清)。而epoll是通过事件驱动的方式,当有FD准备就绪的时候,立即回调函数rollback。如图:
IO多路复用模型
谈到epoll,不得不提一个经典的问题,apache和nginx的对比,为什么nginx比apache效率高很多,这就是根本的原因。
信号驱动:
这种模型在实际应用的非常少,这里不做过多介绍,可以看图:
信号驱动的IO模型
异步:
告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核空间拷贝到自己的缓冲区)通知。异步IO的主要特点是完成操作后主动通知。如图:
异步IO模型

好,上面的可能有点抽象。下面用通俗点的语言来总结一下阻塞,非阻塞,同步,异步
阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待;
同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;
异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。
再举个网上流传的,非常容易理解的例子:
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)老张觉得自己聪明了。
所谓同步异步,只是对于水壶而言。普通水壶,同步;响水壶,异步。虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。所谓阻塞非阻塞,仅仅对于老张而言。立等的老张,
阻塞;看电视的老张,非阻塞。情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。
虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

目录
相关文章
|
Kubernetes 安全 Devops
【云效流水线 Flow 测评】驾驭云海:五大场景下的云效Flow实战部署评测
云效是一款企业级持续集成和持续交付工具,提供免费、高可用的服务,集成阿里云多种服务,支持蓝绿、分批、金丝雀等发布策略。其亮点包括快速定位问题、节省维护成本、丰富的企业级特性及与团队协作的契合。基础版和高级版分别针对小型企业和大规模团队,提供不同功能和服务。此外,云效对比Jenkins在集成阿里云服务和易用性上有优势。通过实战演示了云效在ECS和K8s上的快速部署流程,以及代码质量检测和AI智能排查功能,展示了其在DevOps流程中的高效和便捷,适合不同规模的企业使用。本文撰写用时5小时,请各位看官帮忙多多支持,如有建议也请一并给出,您的建议能帮助我下一篇更加出色。
219153 19
|
Ubuntu
Ubuntu 20.04 安装 emsdk
Ubuntu 20.04 安装 emsdk
953 0
|
8月前
|
数据采集 SQL 数据处理
当实时消费遇到 SPL:让数据处理更高效、简单
SLS 对实时消费进行了功能升级,推出了 基于 SPL 的规则消费功能。在实时消费过程中,用户只需通过简单的 SPL 配置即可完成服务端的数据清洗和预处理操作。通过SPL消费可以将客户端复杂的业务逻辑“左移”到服务端,从而大幅降低了客户端的复杂性和计算开销。
364 56
|
机器学习/深度学习 人工智能 算法
"拥抱AI规模化浪潮:从数据到算法,解锁未来无限可能,你准备好迎接这场技术革命了吗?"
【10月更文挑战第14天】本文探讨了AI规模化的重要性和挑战,涵盖数据、算法、算力和应用场景等方面。通过使用Python和TensorFlow的示例代码,展示了如何训练并应用一个基本的AI模型进行图像分类,强调了AI规模化在各行业的广泛应用前景。
230 5
|
Oracle 关系型数据库 MySQL
CentOS7安装MariaDB成功的实践
CentOS7安装MariaDB成功的实践
372 0
|
Unix Linux 开发工具
linux笔记 diff及patch的制作与使用
这篇文章是关于Linux系统中使用`diff`命令生成补丁文件以及使用`patch`命令应用这些补丁的详细教程和实战案例。
573 2
linux笔记 diff及patch的制作与使用
|
11月前
|
人工智能 安全 Linux
重磅!阿里云正式成为FinOps基金会顶级会员!
1月23日,FinOps基金会宣布阿里云正式加入成为顶级会员。
|
缓存 JavaScript 前端开发
微信 JS-SDK Demo “分享信息设置” API 及数字签名生成方法(NodeJS版本)
微信 JS-SDK Demo “分享信息设置” API 及数字签名生成方法(NodeJS版本)更新时间(2020-10-29)
|
Java 知识图谱
知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - Java SpringBoot 操作 Neo4j
知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - Java SpringBoot 操作 Neo4j
747 0
|
数据挖掘
R语言方差分析(ANOVA):理解与应用
【8月更文挑战第31天】ANOVA是一种强大的统计方法,用于比较三个或更多组之间的均值差异。在R语言中,我们可以轻松地使用`aov()`函数进行ANOVA分析,并通过后置检验(如TukeyHSD检验)来进一步分析哪些组之间存在显著差异。ANOVA在多个领域都有广泛的应用,是数据分析中不可或缺的工具之一。
1377 1