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

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&#xff0c;Input/Output&#xff0c;即输入/输出。从计算机结构来看&#xff0c;IO描述了计算机系统和外部设备之间通讯的过程。从应用程序角度来看&#xff0c;一个进程的地址空间划分为 用户空间&#xff08;User space&#xff09; 和 内核空…...

【Python网络爬虫笔记】14-使用代理绕过访问限制

【Python网络爬虫笔记】14-网络代理 目录什么是代理&#xff1f;为什么需要使用代理&#xff1f;代理的类型如何在Python中使用代理&#xff1f;使用requests库设置代理使用urllib库设置代理使用scrapy框架设置代理 典型案例&#xff1a;使用代理爬取豆瓣电影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权限管理文件访问者的分类&#xff08;人&#xff09;文件类型和访问权限&#xff08;事物属性&#xff09;文件权限值的表示方法文件访问权限的相关设置方法如…...

Java中的缓存技术:Guava Cache vs Caffeine vs Redis

在Java中&#xff0c;缓存技术是提升应用性能的重要手段。常见的缓存技术包括Guava Cache、Caffeine和Redis。它们各有优缺点&#xff0c;适用于不同的场景。以下是对它们的详细对比&#xff1a; 1. Guava Cache 类型: 本地缓存 特点: 基于内存的缓存&#xff0c;适用于单机应…...

C# 弃元的使用

总目录 前言 在C# 7.0及更高版本中&#xff0c;弃元&#xff08;Discard&#xff09;是一个新的语言特性&#xff0c;允许开发者在特定情况下忽略某些值。弃元用下划线 _ 作为占位符&#xff0c;明确表示忽略某个值&#xff0c;提升代码可读性 一、弃元是什么&#xff1f; 1.…...

OceanBase数据库实战:Windows Docker部署与DBeaver无缝对接

一、前言 OceanBase 是一款高性能、高可扩展的分布式数据库&#xff0c;适用于大规模数据处理和企业级应用。 随着大数据和云计算的普及&#xff0c;OceanBase 在企业数字化转型中扮演着重要角色。学习 OceanBase 可以帮助开发者掌握先进的分布式数据库技术&#xff0c;提升数…...

技术速递|.NET 9 网络优化

作者&#xff1a;Mňa&#xff0c;Natalia&#xff0c;Anton 排版&#xff1a;Alan Wang 秉承我们的传统&#xff0c;我们很高兴与您分享这篇博客文章&#xff0c;以介绍新的 .NET 版本中网络领域相关的最新动态和最有趣的变化。今年&#xff0c;我们带来了 HTTP 领域的改变、新…...

如何让 Git 管理本地项目

如何让 Git 管理本地项目&#xff1a;详细步骤指南 Git 是最流行的分布式版本控制系统&#xff0c;能够高效管理项目的代码变更历史。以下是将本地项目交给 Git 管理的完整流程&#xff0c;适用于首次使用 Git 的开发者。 一、前置条件 安装 Git 二、初始化 Git 仓库 进入项目…...

如何进行OceanBase 运维工具的部署和表性能优化

本文来自OceanBase 用户的实践分享 随着OceanBase数据库应用的日益深入&#xff0c;数据量不断攀升&#xff0c;单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此&#xff0c;部署专门的运维工具、实施针对性的表性能优化策略&#xff0c;以及加强指标监测工作&…...

Tag标签的使用

一个非常适合运用在vue项目中的组件&#xff1a;Tag标签。 目录 一、准备工作 1、安装element-plus库 2、配置element-plus库 二、Tag标签入门 1、打开element官网&#xff0c;搜索tag标签 2、体验Tag标签的基础用法 三、Tag标签进阶训练1 1、定义一个数组&#xff0c;…...

DeepSeek系统架构的逐层分类拆解分析,从底层基础设施到用户端分发全链路

一、底层基础设施层 1. 硬件服务器集群 算力单元&#xff1a; GPU集群&#xff1a;基于NVIDIA H800/H100 GPU构建&#xff0c;单集群规模超10,000卡&#xff0c;采用NVLink全互联架构实现低延迟通信。国产化支持&#xff1a;适配海光DCU、寒武纪MLU等国产芯片&#xff0c;通过…...

Linux:(3)

一&#xff1a;Linux和Linux互传&#xff08;压缩包&#xff09; scp:Linux scp 命令用于 Linux 之间复制文件和目录。 scp 是 secure copy 的缩写, scp 是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令。 scp 是加密的&#xff0c;rcp 是不加密的&#xff0c;scp 是…...

el-select滚动获取下拉数据;el-select滚动加载

el-select下拉获取数据 1.解决问题2.封装MyScrollSelect组件3.使用MyScrollSelect组件 1.解决问题 场景&#xff1a;下拉数据量过大&#xff0c;后端提供一个分页查询接口&#xff1b;需要每次滚动加载下一页的下拉数据 且单选的状态&#xff0c;需要支持回显&#xff0c;通过n…...

HarmonyOS 5.0应用开发——鸿蒙接入高德地图实现POI搜索

【高心星出品】 文章目录 鸿蒙接入高德地图实现POI搜索运行结果&#xff1a;准备地图编写ArkUI布局来加载HTML地图 鸿蒙接入高德地图实现POI搜索 在当今数字化时代&#xff0c;地图应用已成为移动设备中不可或缺的一部分。随着鸿蒙系统的日益普及&#xff0c;如何在鸿蒙应用中…...

计算机视觉(opencv-python)入门之常见图像处理基本操作(待补充)

图像预处理是计算机视觉任务中的关键步骤&#xff0c;它通过对原始图像进行处理&#xff0c;以提高后续图像分析、特征提取和识别的准确性。 示例图片 目录 常见图像预处理方法 灰度化处理 法一 法二 说明 切片截取部分图像数据 cv2.cvtColor() 颜色空间转换 cv2.spli…...

采用DDNS-GO与cloudflare实现双域名同时访问NAS

这个标题其实解释的还不够清楚&#xff0c;本人是小白&#xff0c;但是买了群晖的NAS后自己瞎折腾了一下&#xff0c;遇到了如下的问题&#xff1a; 1、家里是移动宽带&#xff0c;没有公网IP&#xff0c;因此Ipv4无法使用&#xff0c;IPV6可以正常使用。 2、办公室场地采用的…...

w803|联盛德|WM IoT SDK2.X测试|pinout|(2):w803开发板简介

概述 W803-Pico是一款基于联盛德W803芯片为主控的开发板&#xff0c;支持IEEE802.11 b/g/n Wi-Fi&#xff0c;以及BT/BLE4.2协议蓝牙。芯片内置高性能32位处理器&#xff0c;主频高达240MHz。内置2MB Flash以及288KB RAM。硬件采用DIP封装&#xff0c;PCB板载天线&#xff0c;…...

【UCB CS 61B SP24】Lecture 16 - Data Structures 2: ADTs, BSTs学习笔记

本文首先介绍了抽象数据类型与树的概念&#xff0c;接着重点讲解二叉搜索树的定义与操作方式&#xff0c;并用 Java 实现一个标准的二叉搜索树结构。 1. 抽象数据类型 首先引入一个概念叫做抽象数据类型&#xff08;Abstract Data Type&#xff0c;ADT&#xff09;&#xff0…...

RabbitMQ系列(零)概要

一、消息队列总览 1. 什么是消息队列&#xff1f; 消息队列&#xff08;Message Queue&#xff09;是一种异步通信机制&#xff0c;允许分布式系统中的服务通过生产-消费模型传递数据。其核心价值在于&#xff1a; 解耦性&#xff1a;生产者与消费者无需同时在线或直接交互削…...

Java 大视界 -- Java 大数据在智能物流路径规划与车辆调度中的创新应用(102)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

HarmonyOS Design 介绍

HarmonyOS Design 介绍 文章目录 HarmonyOS Design 介绍一、HarmonyOS Design 是什么&#xff1f;1. 设计系统&#xff08;Design System&#xff09;2. UI 框架的支持3. 设计工具和资源4. 开发指南5. 与其他设计系统的对比总结 二、HarmonyOS Design 特点 | 应用场景1. Harmon…...

云计算如何解决延迟问题?

在云计算中&#xff0c;延迟&#xff08;latency&#xff09;指的是从请求发出到收到响应之间的时间间隔。延迟过高可能会严重影响用户体验&#xff0c;特别是在需要实时响应的应用中&#xff0c;如在线游戏、视频流、金融交易等。云计算服务如何解决延迟问题&#xff0c;通常依…...

【算法系列】快速排序详解

文章目录 快速排序的多种实现方式1. 基本快速排序&#xff08;Lomuto 分区方案&#xff09;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. 数字键盘区 笔记本电脑键盘的功能区&#xff0c;使用前需先按Fn键 1.1、功能区 ESC&#xff1a;退出 F1&#xff1a;显示帮助信息 F2&#xff1a;重命名 F4&#xff1a;重复上一步操作 F5&#xff1a;刷新网页 …...

Grok 3 vs. DeepSeek vs. ChatGPT:2025终极AI对决

2025 年,AI 领域的竞争愈发激烈,三个重量级选手争夺霸主地位:Grok 3(由 xAI 开发)、DeepSeek(国内 AI 初创公司)和 ChatGPT(OpenAI 产品)。每个模型都有自己独特的优势,无论是在深度思考、速度、编程辅助、创意输出,还是在成本控制方面,都展现出强大的实力。但究竟…...

【MySQL篇】数据库基础

目录 1&#xff0c;什么是数据库&#xff1f; 2&#xff0c;主流数据库 3&#xff0c;MySQL介绍 1&#xff0c;MySQL架构 2&#xff0c;SQL分类 3&#xff0c;MySQL存储引擎 1&#xff0c;什么是数据库&#xff1f; 数据库&#xff08;Database&#xff0c;简称DB&#xf…...

vscode java环境中文乱码的问题

先说我的结论&#xff1a; 由于我的系统是windows的&#xff0c;所以vscode使用的是默认gbk的编码进行的。 但是我的目的是全部都使用utf-8&#xff0c;因为我的程序始终是要去linux上去运行的&#xff0c;总不能在本地是好的&#xff0c;然后到服务器上就不行了吧&#xff0c;…...

基于SpringBoot+mybatisplus+vueJS的Cosplay文化展示与交流社区设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…...

组件传递props校验

注意&#xff1a;prop是只读的&#xff01;不可以修改父组件的数据。 可以检验传过来的内容是否类型没问题。 App.vue <template><div><!-- <parentDemo/> --><componentA/></div></template> <script> import ComponentA …...