IO 概念
一个基本的 IO,它会涉及到两个系统对象,一个是调用这个 IO 的进程对象,另一个就是系统内核 (kernel)。当一个 read 操作发生时,它会经历两个阶段:
- 通过 read 系统调用想内核发起读请求。
- 内核向硬件发送读指令,并等待读就绪。
- 内核把将要读取的数据复制到描述符所指向的内核缓存区中。
- 将数据从内核缓存区拷贝到用户进程空间中。
IO 模型对比
从等待数据和数据复制这两个时间段,指出了不同 I/O 模型的区别
🍛 类比餐厅吃饭
看了几篇文章,为了加深理解,我做了文字排版上的优化,方便从相似的地方发现他们本质上的不同。
- 我们去餐厅吃饭,会经过以下几个步骤:
- 首先你(用户态进程)在饭店(内核态的进程)根据菜单点菜
- 然后等待厨房准备好 ⇒ 等待数据
- 接着服务员(内核态的进程)上菜 ⇒ 将数据从内核复制到用户空间
- 只点一个菜
- 然后在餐桌上开始等待
- 你在这个过程中什么事都不干
- 直到服务员上菜 ⇒
阻塞式 I/O 模型
- 等了一会儿然后就去问服务员,不断重复问,直到服务员上菜 ⇒
非阻塞式 I/O 模型
- 直到服务员上菜 ⇒
- 你给服务员留下手机,告诉他菜准备好的话
- 先不要上菜,打个电话给你,然后你就出去玩耍了
- 等到菜准备好了,服务员手机通知你,你立马回到了餐厅
- 你对服务员说 “你现在可以上菜了”,于是你在餐桌上等待服务员把菜送上来,然后吃饭。 ⇒
信号驱动式 I/O 模型
- 你对服务员说 “你现在可以上菜了”,于是你在餐桌上等待服务员把菜送上来,然后吃饭。 ⇒
- 等到菜准备好了,服务员手机通知你,你立马回到了餐厅
- 先上菜,菜上桌了打电话给你,然后你就出去玩耍了
- 等到菜上桌了,服务员手机通知你,你立马回到了餐桌
- 开始吃饭。 ⇒
异步 I/O 模型
- 开始吃饭。 ⇒
- 等到菜上桌了,服务员手机通知你,你立马回到了餐桌
- 先不要上菜,打个电话给你,然后你就出去玩耍了
- 你在这个过程中什么事都不干
- 然后在餐桌上开始等待
- 你点了很多菜
- 然后在餐桌上开始等待
- 你在这个过程中什么事都不干
- 某个时刻其中一个菜或者多个菜厨房里同时好了,
- 服务员跑过来说,“亲,您的有些菜好了,要现在上桌么?”
- 你回答,现在就上,于是服务员上一个菜(服务员一次只能上一个菜),你就吃完一个,上一个你就吃完一个 ⇒
I/O 复用模型
- 某个时刻其中一个菜或者多个菜厨房里同时好了,
- 你在这个过程中什么事都不干
- 然后在餐桌上开始等待
参考资料: