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

编程领域的IO模型(BIO,NIO,AIO)

目前对于市面上绝大多数的应用来说,不能实现的业务功能太少了。更多的是对底层细节,性能优化的追求。其中IO就是性能优化中很重要的一环。Redis快,mysql缓冲区存在的意义。都跟IO有着密切关系。IO其实我们都在用,输入输出流这块。但是没关注到计算机组成原理那块我觉得还是差点意思。把整个IO理解清楚,就得从计算机的交互开始。我近期学习了很多篇IO文章,特地做下总结。

首先大概念,IO,输入输出。

输入理解为键盘,输入给谁,肯定是电脑。输入到电脑里做什么,一般就是用做存储。那就可以理解为从外部媒介到电脑内核这个过程就是输入。同理经过电脑内核展现出来的就叫输出。那么电脑内核在做什么事?电脑内核又分为用户空间和内核空间。内核空间是操作系统层面的,用户无权直接访问。用户空间是个人的。它与内核空间做任何信息交互就是我们编程领域说的IO了。一次操作系统的IO分数据准备和数据复制。讲到IO就离不开IO模型。IO模型理解就是同样操作,不同模型产生不同效率的一种方式。常见的三种 BIO,NIO,AIO。NIO中又多分为select,poll.epoll模式(这三类模式多路复用),说白了就是操作系统提供的三类监听socket的函数。NIO中又提出了事件驱动和信号驱动的概念。其中epoll模式的信号驱动就是目前主流的IO模型。很多源码中用的都是这种模型。


就很直观举个例子,理解下各类IO模型。但例子仅仅是针对IO中的数据准备阶段

小明去吃饭,餐厅总共有五个位置。到那里发现没位置了,就一直等。等到有位置就可以吃。这是BIO。

小明去吃饭,餐厅总共有五个位置。到那里发现没位置了,餐厅告诉他晚点再来,于是他就走了第二次再来询问有没有位置,直到他问到刚好有位置了就可以吃。这是NIO。

小明去吃饭,餐厅总共有五个位置。到那里发现没位置了,餐厅告诉他等有位置了再通知他来,于是他只是约了号,餐厅有位置了就告诉他来吃,但此时他是不知道是哪个位置。只能自己去再问一次哪个位置空缺了。这是NIO多路复用。采用事件驱动。

为了解决不知道是哪个位置的无效遍历,加上了信号驱动。epoll中用的就是这个模式。

把上面的所有问题统一为一类,都是为了解决数据准备阶段的监听回复。但没解决数据复制阶段的阻塞。那块还是同步的。AIO就是把NIO的epoll模式后面数据复制的过程也做成异步。就完成了真正意义上的异步。


再分析下每种模型的指令,就是因为发送的指令不同才呈现出不同的效果。

BIO 直接发送recvfrom指令,并且内核无明确返回。

NIO 直接发送recvfrom指令,并且内核明确返回EWOULDBLOCK错误码表示未准备好数据。

NIO多路复用-select模式。发送select指令,等待内核返回任意一个。都是同一个进程发起的select指令会监听内核中的多个fd。fd就是每操作文件是内核的一个状态码。select模式监听的IO最大连接数有限,在Linux系统上一般为1024。因为采用的是固定长度的 BitsMap实现。

NIO多路复用-poll模式。发送poll指令,同select模式。等待内核返回任意一个。都是同一个进程发起的select指令会监听内核中的多个fd。poll模式采用动态数组实现,主要解决了的IO最大连接数有限问题。

NIO多路复用-epoll模式。主要三个指令epoll_create、epoll_ctl、epoll_wait。发送epoll_create指令,一旦基于某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这时候是能精确定位到fd的。但还存在一次调用epoll_wait调用主动询问的过程。于是便出现了信号驱动IO,信号驱动不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号,调用sigaction的时候建立一个SIGIO的信号。内核数据准备好后,再通过SIGIO信号通知应用进程。这样就不需要主动询问了。

AIO直接发送aio-read指令,就可以完成全部流程的操作。


I/O模型的应用非常广泛,它们被集成在多种主流框架中以提高性能和可扩展性。如Netty,Redis。理解这些I/O模型的原理和特点,可以帮助我们更好地设计和优化程序,提高系统的性能和可靠性。希望本文能够帮助读者深入理解I/O模型。

参考 看一遍就理解:IO模型详解 - 知乎

http://www.lryc.cn/news/533510.html

相关文章:

  • DeepSeek和ChatGPT的对比
  • Pyqt 的QTableWidget组件
  • 4. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--什么是微服务--微服务设计原则与最佳实践
  • 网络安全威胁框架与入侵分析模型概述
  • 树和二叉树_7
  • 不同标签页、iframe或者worker之间的广播通信——BroadcastChannel
  • 开源CodeGPT + DeepSeek-R1 是否可以替代商业付费代码辅助工具
  • AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA的CAN FD汽车总线数据交互系统设计
  • STC51案例操作
  • 多光谱技术在华为手机上的应用发展历史
  • C语言:函数栈帧的创建和销毁
  • NLP_[2]_文本预处理-文本数据分析
  • 【工具篇】深度揭秘 Midjourney:开启 AI 图像创作新时代
  • 从O(k*n)到O(1):如何用哈希表终结多层if判断的性能困局
  • 视频采集卡接口
  • 蓝桥杯真题 - 像素放置 - 题解
  • vue基础(三)
  • 使用Python开发PPTX压缩工具
  • ubuntu24.04安装布置ros
  • SQL 秒变 ER 图 sql转er图
  • 【AI知识点】如何判断数据集是否噪声过大?
  • 网络安全治理架构图 网络安全管理架构
  • 如何写出优秀的单元测试?
  • 数据留痕的方法
  • 机器学习数学基础:19.线性相关与线性无关
  • ArgoCD实战指南:GitOps驱动下的Kubernetes自动化部署与Helm/Kustomize集成
  • JVM虚拟机以及跨平台原理
  • 【AIGC提示词系统】基于 DeepSeek R1 + ClaudeAI 易经占卜系统
  • 电路笔记 : opa 运放失调电压失调电流输入偏置电流 + 反向放大器的平衡电阻 R3 = R1 // R2 以减小输出直流噪声
  • ScrapeGraphAI颠覆传统网络爬虫技术