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 是内核数据准备好数据从内核态拷⻉到⽤户态这两个过程都不⽤等待

相关推荐
Mr.Pascal3 小时前
Redis:主动更新,读时更新,定时任务。三种的优劣势对比
数据库·redis·缓存
思成不止于此3 小时前
【MySQL 零基础入门】DQL 核心语法(二):表条件查询与分组查询篇
android·数据库·笔记·学习·mysql
骥龙3 小时前
3.10、构建网络防线:防火墙、WAF 与蜜罐实战
服务器·网络·数据库·网络安全
九河云4 小时前
华为云 ECS 弹性伸缩技术:应对业务峰值的算力动态调度策略
大数据·服务器·人工智能·物联网·华为云
云宏信息5 小时前
运维效率提升实战:如何用轻量化云管平台统一纳管与自动化日常资源操作
运维·服务器·网络·架构·云计算
gugugu.5 小时前
Redis 字符串类型完全指南:从原理到实战应用
数据库·redis·缓存
杨云龙UP5 小时前
MySQL 自动备份与覆盖恢复实战:一套脚本搞定全库/按库备份恢复
linux·运维·数据库·sql·mysql
sjg200104146 小时前
Deepin 20.9 误装gcc-8-base_8.4.0-1ubuntu1~16.04.1_amd64 后卸载
linux·运维·服务器
workflower6 小时前
PostgreSQL 数据库优化
数据库·团队开发·数据库开发·时序数据库·数据库架构
jerryinwuhan6 小时前
1210_1 Linux
linux·运维·服务器