BIO、NIO、AIO的区别

什么是IO?

I/O 描述了计算机系统与外部设备之间通信的过程

程序在用户空间对操作系统的内核发起IO调用,具体 IO 的执行是由操作系统的内核来完成的。

当应用程序发起 I/O 调用后,会经历两个步骤:

  1. 内核等待 I/O 设备准备好数据
  2. 内核将数据从内核空间拷贝到用户空间。

BIO:同步阻塞IO。

应用程序发起 read 调用后,会一直阻塞,直到内核把数据拷贝到用户空间,阻塞等待的是内核数据准备好和数据从内核态拷⻉到⽤户态这两个过程。不适用于高并发量

NIO:非阻塞IO。

⾮阻塞的 read 请求在数据未准备好的情况下⽴即返回,可以继续往下执⾏,此时应⽤程序不断轮询内核,直到数据准备A好,内核将数据拷⻉到应⽤程序缓冲区, read 调⽤才可以获取到结果**。**

问题:应用程序要一直轮询

基于非阻塞的I/O 多路复用模型。

**当内核数据准备好时,以事件通知应⽤程序进⾏操作。**于 Java 1.4 中引入,对应 java.nio 包。一个进程/线程维护多个 Socket,这个多路复用就是多个连接复用一个进程/线程。

select

    • 将已连接的 Socket 都放到⼀个**⽂件描述符集合**fd_set,然后调⽤ select 函数将 fd_set 集合拷⻉到内核⾥,让内核来检查是否有⽹络事件产⽣,检查的⽅式很粗暴,就是通过遍历 fd_set 的⽅式,当检查到有事件产⽣后,将此 Socket 标记为可读或可写, 接着再把整个 fd_set 拷⻉回⽤户态⾥,然后⽤户态还需要再通过遍历的⽅法找到可读或可写的 Socket,再对其处理。
    • select 使⽤固定⻓度的 BitsMap,表示⽂件描述符集合,⽽且所⽀持的⽂件描述符的个数是有限制的,在 Linux 系统中,由内核中的 FD_SETSIZE 限制, 默认最⼤值为 1024 ,只能监听 0~1023 的⽂件描述符。
    • 缺点:
      • 1.整个fd_set都需要从内核拷贝到用户态,浪费资源
      • 2.每次调用 select 都需要在内核遍历传递进来的所有 fd_set
      • 每次调用 select 之前都需要遍历设置监听集合,重复工作

poll

    • poll 不再⽤ BitsMap 来存储所关注的⽂件描述符,取⽽代之⽤动态数组,以链表形式来组织,并没有太⼤的本质区别,只是突破了 select 的⽂件描述符个数限制(在 Linux 系统中,由内核中的 FD_SETSIZE 限制, 默认最⼤值为 1024 )

epoll

    • epoll 在内核⾥使⽤红⿊树来跟踪进程所有待检测的⽂件描述字,减少了内核和⽤户空间⼤量的数据拷⻉和内存分配
    • 内核⾥维护了⼀个链表来记录就绪事件,当⽤户调⽤ epoll_wait() 函数时,只会返回有事件发⽣的⽂件描述符的个数

AIO:NIO改进版,异步IO。

是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。真正的异步 I/O 是内核数据准备好数据从内核态拷⻉到⽤户态这两个过程都不⽤等待

相关推荐
zh1570234 小时前
JavaScript中WorkerThreads解决服务端计算瓶颈
jvm·数据库·python
代码AI弗森4 小时前
一文理清楚“算力申请 / 成本测算 / 并发评估”
java·服务器·数据库
^—app5668665 小时前
游戏运存小启动不起来临时解决方法
运维·服务器
摇滚侠5 小时前
expdp 查看帮助
java·数据库·oracle
流年似水~5 小时前
MCP协议实战:从零搭建一个让Claude能“看见“数据库的工具服务
数据库·人工智能·程序人生·ai·ai编程
2401_871492856 小时前
Vue.js监听器watch利用回调函数处理级联下拉框数据联动
jvm·数据库·python
志栋智能6 小时前
超自动化安全:构建智能安全运营的核心引擎
大数据·运维·服务器·数据库·安全·自动化·产品运营
zhoutongsheng7 小时前
C#怎么实现Swagger文档 C#如何在ASP.NET Core中集成Swagger自动生成API文档【框架】
jvm·数据库·python
WinterKay7 小时前
【开源】我写了一个轻量级本地数据库浏览工具,支持 MySQL/Redis 只读查询
数据库·mysql·开源
Edward111111118 小时前
4月28日防火墙问题
linux·运维·服务器