vlambda博客
学习文章列表

「IO 模型」聊聊五种 IO 模型之概念篇

做一个比较注重七寸认知的技术人!

Hello,大家好!我是七寸君。

在系统架构中,高可用、高并发是系统架构的两个关键指标,也是架构复杂度所在。在高并发层面,目标就是在有限资源下,挖掘出无限的性能支撑。在这个过程中,网络 IO 的优化一直是关注的重点。

本文将先从 IO 模型基本概念说起,从概念认知层面达成一致,能够由浅入深的理解其原理。



01



概念说明


用户空间与内核空间

进程切换

为了控制进程的执行,内核必须有能力挂起正在 CPU 上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

从一个进程的运行转到另一个进程上运行,是很消耗资源的,这个过程中经过下面这些变化:

> 1. 保存处理机上下文,包括程序计数器和其他寄存器。

> 2. 更新 PCB 信息。

> 3. 把进程的 PCB 移入相应的队列,如就绪、在某事件阻塞等队列。

> 4. 选择另一个进程执行,并更新其 PCB。

> 5. 更新内存管理的数据结构。

> 6. 恢复处理机上下文。

进程阻塞

在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使进程由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。当进程进入阻塞状态,是不占用CPU资源的

文件描述符 fd

文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于 UNIX、Linux 这样的操作系统。

缓存 IO

缓存 IO 的缺点:



02



Linux IO 模型

所以说,当一个 read 操作发生时,它会经历两个阶段:

> 1. 第一阶段:等待数据准备 (Waiting for the data to be ready)。

> 2. 第二阶段:将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。

对于 Socket 流而言:

> 1. 第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区。

> 2. 第二步:把数据从内核缓冲区复制到应用进程缓冲区。

网络应用需要处理的无非就是两大类问题,网络 IO,数据计算。相对于后者,网络 IO 的延迟,给应用带来的性能瓶颈大于后者。网络 IO 的模型大致有如下几种:

> 1. 同步模型 IO(synchronous IO)

> 2. 阻塞 IO(bloking IO)

> 3. 非阻塞 IO(non-blocking IO)

> 4. 多路复用 IO(multiplexing IO)

> 5. 信号驱动式 IO(signal-driven IO)

> 6. 异步 IO(asynchronous IO)

由于 signal-driven IO 在实际中并不常用,所以我这只提及剩下的四种IO Model。

让我们来探索一下基本 Linux IO 模型的简单矩阵。如下图所示:

以上 IO 模型矩阵,每个 IO 模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。

- EOF -


关注「七寸知架构」加星标,不错过技术那些事儿


        
          
          
        
❤️ 您的 点赞 在看 就是最大的支持❤️