BIO、NIO、AIO解析
一、基础概念
1、IO的含义
IO,Input/Output,即输入/输出。从计算机结构来看,IO描述了计算机系统和外部设备之间通讯的过程。从应用程序角度来看,一个进程的地址空间划分为 用户空间(User space) 和 内核空间(Kernel space ) 。用户进程(应用程序)想要执行 IO 操作的话,必须通过 系统调用 来间接访问内核空间。我们平常开发接触最多的就是磁盘IO(读写文件)和网络IO(网络请求和响应)完整的IO过程:
(1)应用程序进程向操作系统发起IO调用请求。
(2)操作系统准备数据,把IO外部设备(一般指硬盘、socket通讯的网卡)的数据,加载到内核缓冲区。
(3)操作系统拷贝数据,即将内核缓冲区的数据,拷贝到进程缓冲区。
2、同步、异步
发送请求后,被调用者返回请求结果就是同步的,反之,调用者通过注册回调来获得结果就是异步的。
3、阻塞、非阻塞
调用者阻塞等待结果的返回,挂起当前线程,不能执行其它操作就是阻塞的;反之,调用者可以读到是否有结果,有结果就处理,没有结果就可以去执行其它操作了,就是非阻塞的。
二、IO模型
1、同步阻塞IO模型(BIO)
应用程序发起IO调用,如果内核的数据还没准备好的话,应用程序进程一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示。socket服务端单线程阻塞监听客户端连接,有连接来了就接着往下执行,然后创建一个新的线程去处理连接的读写操作。服务端除了监听的线程,还要为每个客户端连接建立一个新的线程,一个线程对应处理一个客户端连接请求,不适合高并发场景。

在客户端连接数量不高的情况下,是没问题的。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
2、同步非阻塞IO模型(NIO)

NIO中的N可以理解为Non-blocking,不单纯是New。NIO虽然说是非阻塞的,但是应有程序在等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的。Java 中的 NIO 于 Java 1.4 中引入,对应 java.nio 包,提供了 Channel , Selector,Buffer 等抽象。它支持面向缓冲的,基于通道的 I/O 操作方法。通过选择器Selector轮询有没有客户端连接或读写事件,如果监听到客户端连接ServerSocketChannel,就注册到Selector进行读写事件监听;如果监听到读写事件SocketChannel,进行读写操作;如果没监听到,通过while (selector.select() > 0) 判断持续监听。对于高负载、高并发的(网络)应用,应使用 NIO 。

它相对于阻塞IO,虽然大幅提升了性能,但是它依然存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的CPU资源。可以用IO多路复用模型,去解决这个问题。
3、IO多路复用模型
系统提供一系列函数(如select、poll、epoll函数),它们可以同时监控多个文件描述符fd的操作,任何一个返回内核数据就绪,应用进程再发起系统调用。

(1)IO多路复用之select

NIO模型,需要N(N>=1)次轮询系统调用,然而基于select的IO多路复用模型只需要发起一次系统调用,通过调用select函数,可以同时监控多个文件描述符fd(File Descriptor),在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起请求去读取数据。但是select有如下缺点:
- 监听的IO最大连接数有限,在Linux系统上一般为1024。
- select函数返回后,是通过遍历fdset,找到就绪的描述符fd。(仅知道有I/O事件发生,却不知是哪几个流,所以遍历所有流)
(2)IO多路复用之poll
与select相比,poll解决了连接数限制问题。但是,poll还是需要通过遍历fd来获取已经就绪的socket。如果同时连接的大量客户端在一时刻可能只有极少处于就绪状态,伴随着监视的fd数量的增长,效率也会线性下降。
(3)IO多路复用之epoll

epoll注册需要监听的fd,一旦某个fd就绪,内核采用回调机制,通知进程。采用监听事件回调的机制,避免了遍历文件描述符的操作。epoll明显优化了IO的执行效率,但在进程监听系统调用时,仍然是阻塞的。windows系统不支持epoll模式,linux系统优先使用epoll模式,可以通过参数改变其它模式。
4、IO模型之信号驱动模型

信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号,然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过信号通知应用进程。应用用户进程收到信号之后,立即去读取数据。但是,数据从内核复制到用户空间的缓冲区,进程还是阻塞的。
5、IO 模型之异步IO(AIO)
BIO、NIO和信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的,因此都不是真正的异步。AIO实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。

BIO、NIO、AIO对比图:

三、应用场景
BIO适合连接数目较少且固定的架构。比较经典的应用就是阻塞socket、Java BIO。
NIO适合连接数目多,但是并发读写操作相对较少的场景。例如netty。
AIO则适合连接数目多,且并发读写操作也多的场景。
四、生活中案例
(1)烧水的案例
- 小时候我妈让我烧水,我比较笨,在水壶旁傻等,也不敢去玩(同步阻塞BIO)。
- 等长大点,知道了水在烧着,中间可以去干其它事情,时不时来看看水开了没(同步非阻塞NIO)。
- 等到我家用上了水开了会发出声音的壶,听到声音了我就知道水开了,在这期间我可以随便干自己的事情(异步非阻塞AIO)。
我在水壶旁傻等就是阻塞的,我可以去干其它事情就是非阻塞的;水壶水烧开了,自动通知我就是异步的,不自动通知我,需要我去看就是同步的。
(2)买烧鸡的案例 - 小明去吃北京烤鸭,取了号在那排队,等了一小时,然后才吃到。(同步阻塞BIO)
- 小红去吃北京烤鸭,也取了号,她一看要等挺久的,于是去逛会商场,每次逛一下,就跑回来看看,是不是轮到她了。于是最后她逛了商场,又吃到了北京烤鸭。(同步非阻塞NIO)
- 小华一样,由于他是高级会员,所以店长说,你去商场随便逛会吧,等下有位置了,我立马打电话给你。于是小华不用干巴巴坐着等,也不用每过一会儿就跑回来看有没有等到,最后也吃上了北京烤鸭。(异步非阻塞AIO)
排队等就是阻塞的,可以去逛商场做其它事情就是非阻塞的;烤鸭店主动电话通知就是异步的,不主动带电话通知,就是同步的。
(3)转账
同步阻塞BIO:页面Loading,等待接口返回转账是否成功。
同步非阻塞NIO:页面显示中间状态,定时任务去调用接口,看是否转账成功。
异步非阻塞AIO:页面调用接口,接口异步返回处理中状态并显示,等到转账结果出来通过WebSocket发送给前端展示。

五、其它
1、内核从磁盘加载数据到pageCahe,多个程序可以共享一个pageCache,但是对应seek不一样。lru 写pageCahe脏的页,将脏页写入磁盘,就不是脏页了,内存不够就会把非脏页淘汰掉。pageCahe优化IO性能,但是不能保证完全不丢数据。
2、硬件有缓存、内核有缓存、进程有缓存(堆内是jvm堆里的,堆外是jvm堆外)。mmap是进程直接调用内核的pageCache。效率上 on heap<off heap<mmap。
3、socket bio 监听客户端连接,监听到就新建一个线程去接受处理信息。
4、netstat -natp //查看建立的连接
lsof -p pid //查看该进程的文件描述符
nc ip 端口 //linux建立socket客户端连接
nc -l ip 端口 //linux建立socket服务端端连接
参考博客:
https://blog.51cto.com/u_12897/11291128
https://blog.csdn.net/u010365819/article/details/119042870
https://blog.csdn.net/weixin_68074170/article/details/140724151
https://blog.csdn.net/qq_43842093/article/details/132769520
www.kegel.com/c10k.html
相关文章:
BIO、NIO、AIO解析
一、基础概念 1、IO的含义 IO,Input/Output,即输入/输出。从计算机结构来看,IO描述了计算机系统和外部设备之间通讯的过程。从应用程序角度来看,一个进程的地址空间划分为 用户空间(User space) 和 内核空…...
【Python网络爬虫笔记】14-使用代理绕过访问限制
【Python网络爬虫笔记】14-网络代理 目录什么是代理?为什么需要使用代理?代理的类型如何在Python中使用代理?使用requests库设置代理使用urllib库设置代理使用scrapy框架设置代理 典型案例:使用代理爬取豆瓣电影Top250步骤1&#…...
⭐算法OJ⭐位操作实战(C++ 实现)190. Reverse Bits | 268. Missing Number | 338. Counting Bits
文章目录 190. Reverse Bits逐位反转思路步骤代码复杂度分析 268. Missing Number338. Counting Bits动态规划 最低有效位思路步骤代码复杂度分析 动态规划 最后设置位思路步骤代码复杂度分析 190. Reverse Bits Reverse bits of a given 32 bits unsigned integer. 逐位反…...
Linux中Shell运行原理和权限(下)(4)
文章目录 前言一、Shell的运行原理二、Linux当中的权限问题Linux权限的概念如何将普通用户添加到信任列表 三、Linux权限管理文件访问者的分类(人)文件类型和访问权限(事物属性)文件权限值的表示方法文件访问权限的相关设置方法如…...
Java中的缓存技术:Guava Cache vs Caffeine vs Redis
在Java中,缓存技术是提升应用性能的重要手段。常见的缓存技术包括Guava Cache、Caffeine和Redis。它们各有优缺点,适用于不同的场景。以下是对它们的详细对比: 1. Guava Cache 类型: 本地缓存 特点: 基于内存的缓存,适用于单机应…...
C# 弃元的使用
总目录 前言 在C# 7.0及更高版本中,弃元(Discard)是一个新的语言特性,允许开发者在特定情况下忽略某些值。弃元用下划线 _ 作为占位符,明确表示忽略某个值,提升代码可读性 一、弃元是什么? 1.…...
OceanBase数据库实战:Windows Docker部署与DBeaver无缝对接
一、前言 OceanBase 是一款高性能、高可扩展的分布式数据库,适用于大规模数据处理和企业级应用。 随着大数据和云计算的普及,OceanBase 在企业数字化转型中扮演着重要角色。学习 OceanBase 可以帮助开发者掌握先进的分布式数据库技术,提升数…...
技术速递|.NET 9 网络优化
作者:Mňa,Natalia,Anton 排版:Alan Wang 秉承我们的传统,我们很高兴与您分享这篇博客文章,以介绍新的 .NET 版本中网络领域相关的最新动态和最有趣的变化。今年,我们带来了 HTTP 领域的改变、新…...
如何让 Git 管理本地项目
如何让 Git 管理本地项目:详细步骤指南 Git 是最流行的分布式版本控制系统,能够高效管理项目的代码变更历史。以下是将本地项目交给 Git 管理的完整流程,适用于首次使用 Git 的开发者。 一、前置条件 安装 Git 二、初始化 Git 仓库 进入项目…...
如何进行OceanBase 运维工具的部署和表性能优化
本文来自OceanBase 用户的实践分享 随着OceanBase数据库应用的日益深入,数据量不断攀升,单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此,部署专门的运维工具、实施针对性的表性能优化策略,以及加强指标监测工作&…...
Tag标签的使用
一个非常适合运用在vue项目中的组件:Tag标签。 目录 一、准备工作 1、安装element-plus库 2、配置element-plus库 二、Tag标签入门 1、打开element官网,搜索tag标签 2、体验Tag标签的基础用法 三、Tag标签进阶训练1 1、定义一个数组,…...
DeepSeek系统架构的逐层分类拆解分析,从底层基础设施到用户端分发全链路
一、底层基础设施层 1. 硬件服务器集群 算力单元: GPU集群:基于NVIDIA H800/H100 GPU构建,单集群规模超10,000卡,采用NVLink全互联架构实现低延迟通信。国产化支持:适配海光DCU、寒武纪MLU等国产芯片,通过…...
Linux:(3)
一:Linux和Linux互传(压缩包) scp:Linux scp 命令用于 Linux 之间复制文件和目录。 scp 是 secure copy 的缩写, scp 是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令。 scp 是加密的,rcp 是不加密的,scp 是…...
el-select滚动获取下拉数据;el-select滚动加载
el-select下拉获取数据 1.解决问题2.封装MyScrollSelect组件3.使用MyScrollSelect组件 1.解决问题 场景:下拉数据量过大,后端提供一个分页查询接口;需要每次滚动加载下一页的下拉数据 且单选的状态,需要支持回显,通过n…...
HarmonyOS 5.0应用开发——鸿蒙接入高德地图实现POI搜索
【高心星出品】 文章目录 鸿蒙接入高德地图实现POI搜索运行结果:准备地图编写ArkUI布局来加载HTML地图 鸿蒙接入高德地图实现POI搜索 在当今数字化时代,地图应用已成为移动设备中不可或缺的一部分。随着鸿蒙系统的日益普及,如何在鸿蒙应用中…...
计算机视觉(opencv-python)入门之常见图像处理基本操作(待补充)
图像预处理是计算机视觉任务中的关键步骤,它通过对原始图像进行处理,以提高后续图像分析、特征提取和识别的准确性。 示例图片 目录 常见图像预处理方法 灰度化处理 法一 法二 说明 切片截取部分图像数据 cv2.cvtColor() 颜色空间转换 cv2.spli…...
采用DDNS-GO与cloudflare实现双域名同时访问NAS
这个标题其实解释的还不够清楚,本人是小白,但是买了群晖的NAS后自己瞎折腾了一下,遇到了如下的问题: 1、家里是移动宽带,没有公网IP,因此Ipv4无法使用,IPV6可以正常使用。 2、办公室场地采用的…...
w803|联盛德|WM IoT SDK2.X测试|pinout|(2):w803开发板简介
概述 W803-Pico是一款基于联盛德W803芯片为主控的开发板,支持IEEE802.11 b/g/n Wi-Fi,以及BT/BLE4.2协议蓝牙。芯片内置高性能32位处理器,主频高达240MHz。内置2MB Flash以及288KB RAM。硬件采用DIP封装,PCB板载天线,…...
【UCB CS 61B SP24】Lecture 16 - Data Structures 2: ADTs, BSTs学习笔记
本文首先介绍了抽象数据类型与树的概念,接着重点讲解二叉搜索树的定义与操作方式,并用 Java 实现一个标准的二叉搜索树结构。 1. 抽象数据类型 首先引入一个概念叫做抽象数据类型(Abstract Data Type,ADT)࿰…...
RabbitMQ系列(零)概要
一、消息队列总览 1. 什么是消息队列? 消息队列(Message Queue)是一种异步通信机制,允许分布式系统中的服务通过生产-消费模型传递数据。其核心价值在于: 解耦性:生产者与消费者无需同时在线或直接交互削…...
Java 大视界 -- Java 大数据在智能物流路径规划与车辆调度中的创新应用(102)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
HarmonyOS Design 介绍
HarmonyOS Design 介绍 文章目录 HarmonyOS Design 介绍一、HarmonyOS Design 是什么?1. 设计系统(Design System)2. UI 框架的支持3. 设计工具和资源4. 开发指南5. 与其他设计系统的对比总结 二、HarmonyOS Design 特点 | 应用场景1. Harmon…...
云计算如何解决延迟问题?
在云计算中,延迟(latency)指的是从请求发出到收到响应之间的时间间隔。延迟过高可能会严重影响用户体验,特别是在需要实时响应的应用中,如在线游戏、视频流、金融交易等。云计算服务如何解决延迟问题,通常依…...
【算法系列】快速排序详解
文章目录 快速排序的多种实现方式1. 基本快速排序(Lomuto 分区方案)1.1 基本原理1.2 步骤1.3 Java 实现示例 2. Hoare 分区方案2.1 基本原理2.2 步骤2.3 Java 实现示例 3. 三数取中法3.1 基本原理3.2 步骤3.3 Java 实现示例 4. 尾递归优化4.1 基本原理4.…...
电脑键盘知识
1、键盘四大功能区 1. 功能区 2. 主要信息输入区 3. 编辑区 4. 数字键盘区 笔记本电脑键盘的功能区,使用前需先按Fn键 1.1、功能区 ESC:退出 F1:显示帮助信息 F2:重命名 F4:重复上一步操作 F5:刷新网页 …...
Grok 3 vs. DeepSeek vs. ChatGPT:2025终极AI对决
2025 年,AI 领域的竞争愈发激烈,三个重量级选手争夺霸主地位:Grok 3(由 xAI 开发)、DeepSeek(国内 AI 初创公司)和 ChatGPT(OpenAI 产品)。每个模型都有自己独特的优势,无论是在深度思考、速度、编程辅助、创意输出,还是在成本控制方面,都展现出强大的实力。但究竟…...
【MySQL篇】数据库基础
目录 1,什么是数据库? 2,主流数据库 3,MySQL介绍 1,MySQL架构 2,SQL分类 3,MySQL存储引擎 1,什么是数据库? 数据库(Database,简称DB…...
vscode java环境中文乱码的问题
先说我的结论: 由于我的系统是windows的,所以vscode使用的是默认gbk的编码进行的。 但是我的目的是全部都使用utf-8,因为我的程序始终是要去linux上去运行的,总不能在本地是好的,然后到服务器上就不行了吧,…...
基于SpringBoot+mybatisplus+vueJS的Cosplay文化展示与交流社区设计与实现
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c等开发语言,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架…...
组件传递props校验
注意:prop是只读的!不可以修改父组件的数据。 可以检验传过来的内容是否类型没问题。 App.vue <template><div><!-- <parentDemo/> --><componentA/></div></template> <script> import ComponentA …...
