五大经典IO模型

操作系统的IO

应用程序需要通过操作系统才能执行一些特殊操作,比如磁盘文件读写,内存读写等。因为这些都是比较危险的操作,不能让应用程序操作,应用程序只能通过调用操作系统开放出来的API才能执行。

  • 什么是用户空间?什么是内核空间?

  • 以32位操作系统为例,它为每个进程都分配了4G(2的32次方)的内存空间。这4G可访问的内存空间分为两部分:用户空间和内核空间。内核空间是操作系统内核访问的空间,是受保护的内存空间。用户空间是用户程序访问的内存空间。

用户程序是跑在用户空间中的,不存在实质的IO过程,真正的IO是在操作系统执行的。就是说,应用程序的IO操作分为两个动作:IO调用和IO执行。 IO调用是进程(应用程序的运行态)发起的,而IO执行是操作系统的工作。

操作系统的一次IO过程

应用程序发起的一次IO操作包括两个动作:

  • IO调用:应用进程调用操作系统的API
  • IO执行:操作系统内核完成IO操作

操作系统完成IO操作还包括两个过程:

  • 准备数据阶段:内核等待I/O设备准备好数据
  • 拷贝数据阶段:将数据从内核缓冲区拷贝到用户程序缓冲区。

因此,一次完整的IO操作过程如下:

  1. 应用程序向操作系统发起IO调用请求
  2. 操作系统准备数据,把IO设备的数据加载到内核缓冲区
  3. 操作系统拷贝数据,将数据从内核缓冲区拷贝到用户进程缓冲区

阻塞IO模型

假设应用程序发起IO调用,内核的数据还没准备好,那么用户程序进程就会一直阻塞到内核准备好数据,从内核拷贝到用户空间,才返回成功提示。这就是阻塞IO。

阻塞IO的缺点就是:如果内核数据一直没有准备好,那么用户进程将一直阻塞,这会浪费性能。

非阻塞IO模型(Non-Blocking IO, NIO)

如果内核数据没有准备好,那么先返回错误信息给用户线程。用户线程通过轮询的方式来检查数据是否准备完毕。这就是非阻塞IO。

相对于阻塞IO来说,非阻塞IO虽然提升了性能,但是用户线程频繁进行系统调用,还是会占用大量的CPU资源。

非阻塞IO的流程:

  • 应用进程向操作系统内核发起recvfrom读取数据
  • 操作系统没有准备好数据,返回EWOULDBLOCK错误码
  • 应用程序轮询调用recvfrom
  • 操作系统准备好数据,从内核缓冲区拷贝到用户程序缓冲区
  • 完成调用,返回成功提示

IO多路复用模型

什么是文件描述符fd(File Descriptor)?

文件描述符是计算机科学的一个术语,形式上是一个非负整数。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

IO多路复用模型思路:操作系统提供一类程序(如select、poll、epoll),它们可以同时监控多个fd。任意一个返回内核数据准备就绪,应用进程发起recvfrom系统调用。

信号驱动模型

信号驱动IO不使用主动询问的方式来确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO 的信号),然后应用程序可以去做其他的事。内核准备好数据之后,会通过SIGIO信号通知应用程序数据准备就绪。应用程序接收到信号后,立即调用recvfrom去读取数据。

异步IO模型

前面的BIO、NIO还是信号驱动IO,数据从内核拷贝到用户空间的时候,进程都是阻塞的,因此都不是异步IO。

AIO实现了全流程的非阻塞,就是应用程序发出系统调用后,是立刻返回的,但是返回的不是结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户空间后,就会发出信号通知用户进程IO操作执行完成。

参考

看一遍就理解:IO模型详解 - 知乎 (zhihu.com)

相关推荐
65岁退休Coder1 小时前
LangGraph v1.2.9 节点容错策略 & 流式输出 & 持久化记忆管理
后端·python·langchain
元界metalite3 小时前
SpringBoot整合RocketMQ-毒丸消息还要无限重试吗
后端
SimonKing3 小时前
升级Spring Boot 4后,从 Jackson 2 到 3,到底有哪些变化
java·后端·程序员
YIAN3 小时前
Docker + Nginx 核心原理扫盲:从环境隔离到反向代理,运维面试必考点
后端·docker·面试
万物智能4 小时前
启动链路与分区—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
后端·架构
寒蝉1284 小时前
一个简单操作是怎么在分布式环境下变复杂的
后端
苏三的开发日记4 小时前
Windows宿主机+VMware CentOS虚拟机 + 同一个Wi-Fi下的其他实体电脑,三者可以互相访问
后端
boooooooom4 小时前
手把手做一个图 RAG 烹饪问答系统:Neo4j + Milvus + LLM 的工程实践
前端·javascript·后端
newerp4 小时前
Golang 切片底层结构
后端·程序员·go
BingoGo4 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.0 发布,新增短信服务能力
后端·php