IO 模型
Table of Contents
来源 马哥 Linux 的视频总结:
总的过程
比如, 我们访问 http://www.example.com/index.html 那么我们请求的是 index.html
这个文件存储在服务器的磁盘上
请求–> 内核–> 用户空间(apache 服务器), 然后 apache 服务器知道要访问 index.html –> 磁盘 –> 内核 –> 将 index.html 交给 apache –> apache 发送给请求方
IO 模型
处理数据请求的过程
- 等待数据
磁盘–> 内核
- 复制数据
内核–> 用户空间 (apache 服务器等)
- 用户空间再发送请求方
请求如何被处理
阻塞: 进程发起 IO 调用,未完成之前,当前进程会被挂起
非阻塞: 进程发起 IO 调用,被调用函数完成之前不会阻塞当前进程而是立即返回, 内核告诉进程不要等待, 不要挂起 (忙等待)
请求如何被响应
同步: 进程发起一个过程调用 (功能, 函数) 调用后,在没得到结果之前, 该调用将不会返回
异步: 进程发起一个过程调用, 即便调用者不能立即得到结果, 当调用却会返回, 返回时未完成状态, 当调用完成后, 内核会自行通知调用者已经 OK
IO 模型的 4 种机制
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞: 最高级
IO 模型的 5 种 I/O 模型
- 同步阻塞: 内核不马上做出响应, 调用进程一直在等待, 睡眠, 挂起
- 同步非阻塞: 内核不马上做出响应, 调用进程不睡眠, 不挂起
- I/O 复用 select(1024){prefork}, poll(链表)
- 事件驱动 epoll(linux){event}, wqueue(BSD), 以信号的方式通知
- 边缘触发
- 水平触发
- 边缘触发
- AIO (异步非阻塞, 全程非阻塞)
磁盘 IO 一般支持异步
网络 IO 一般不支持异步
白话理解
假如你去买饭, "我要一盒炒饭", 然后老板没有告诉你饭好了没. 这个就叫同步
假如你去买饭, "我要一盒炒饭", 然后老板告诉你饭等一下就好你先等等. 这个就叫异步
同步阻塞: 假如你去买饭, "我要一盒炒饭", 然后老板饭没有做好, 而且没有告诉你饭好了没 (等到好了再告诉你), 你一直在那里等
同步非阻塞: 一般不用到这个机制, 假如你去买饭, "我要一盒炒饭", 然后老板没有做好, 而且没有告诉你饭好了没, 然后你在附近走了又回来看一下, 又问好了没
异步阻塞: 假如你去买饭, "我要一盒炒饭", 然后老板告诉你饭等一下就好你先等等, 然后你就在那里等
异步非阻塞: 假如你去买饭, "我要一盒炒饭", 然后老板告诉你饭等一下就好你先等等, 然后你在附近走了又回来看一下, 又问好了没
IO 复用:
假如你去买饭, 然后有很多个饭馆, 然后老板饭没有做好, 而且没有告诉你饭好了没 (等到好了再告诉你), 你就去别家, 别家也是如此
你重复的在哪几家转来转去, 直到有一家刚好好了
IO 复用就是不用你去转来转去, 类似于一个公告牌, 直接显示这几家饭馆哪一家好了, 但是你还是要盯着公告牌看
事件驱动:
事件驱动和 IO 复用的区别就是事件驱动买饭的时候, 显示牌会大声告诉你哪家好了, 这个时候你就不用去盯着公告牌
AIO 和事件驱动的区别:
以上的几个 IO 模型, 数据从 内核空间 到 用户空间 的过程中, 还是会处于阻塞状态, 排队! 而 AIO 是真正意义上的异步, 他等到内核到用户空间的这个过程完成之后再通知你, 饭好了