五大经典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)

相关推荐
用户298698530141 分钟前
.NET 文档自动化:Spire.Doc 设置奇偶页页眉/页脚的最佳实践
后端·c#·.net
序安InToo32 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12332 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记35 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0535 分钟前
VS Code 配置 Markdown 环境
后端
navms38 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0538 分钟前
离线数仓的优化及重构
后端
Nyarlathotep011339 分钟前
gin01:初探gin的启动
后端·go
JxWang0540 分钟前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang0541 分钟前
Windows Terminal 配置 oh-my-posh
后端