# 【NO.139】网络IO模型的介绍引出nginx的网络IO模型

## 1. 什么是IO？

  简单来说就是输入输出

## 2. 网络IO经历步骤

- 1. 用户在获取网络资源是在进入网卡，经过网络七层模型将请求交给nginx用户进程
  2. 用户进程无法直接获取磁盘上的资源，会将请求获取什么资源翻译并转发给内核，内核驱动磁盘寻道找到文件（最耗时间的环节）
  3. 文件同样也不能直接交给用户进程，首先磁盘将文件放至内核缓冲区，然后内核告知用户进程请求的资源结果已准备好（耗时比较短）
  4. 内核缓冲区将文件拷贝一份至用户进程缓冲区，用户进程拿到文件 构建响应报文，通过http回传给用户

- ![img](https://pic4.zhimg.com/80/v2-74c2c051ead8d5e7575b4d620c838c63_720w.webp)

- 总结：
- IO总共要经历两个阶段
- 1.磁盘读取数据，将数据拷贝至内核缓冲区
- 2.将内核缓冲区数据拷贝至用户进程缓冲区

------

## 3. 网络IO模型种类

### 3.1.同步阻塞

- 比如你要去完成这样一件事情，把水烧开，灌入暖瓶
- 现在给你一口普通的锅，你也不知道水什么时候可以烧开，你决定守在旁边等待水开。
- 这个时候的你是什么也做不了的，是不是觉得很浪费时间
- 当水开了就需要你把水灌入暖瓶，你还是做不了其他的事情

- ![img](https://pic1.zhimg.com/80/v2-8d30ffd63c1dd5e2c539bfec2ada014c_720w.webp)

### 3.2.同步非阻塞

比如还是烧一锅开水，你还是不知道水什么时候会开，你选择了另外一个策略，去忙其它的事情但是要时不时看下谁开没开

### 3.3.改进了什么呢？

你可以在空挡时间忙其它的事情

### 3.4.增加了什么麻烦呢？

你得时不时的确认水开没开(就意味着得不停的调用cpu，占用cpu资源）

可能你上一次刚看的时候水没开，等你刚看完水开了，那就得等下一次查看的时候才能发现，增加了延迟，等你知道了水开了，自己去把水灌好

![img](https://pic2.zhimg.com/80/v2-d1cbb03b4c24e49aec6527482bc27f39_720w.webp)

### 3.5.异步阻塞

- 这个就比较二了
- 假如给你一个智能热水壶，水开了会自动的提醒你的，但是你还是要傻傻的等
- 完全没有利用好智能热水壶的优势（不做解释）

- ![img](https://pic2.zhimg.com/80/v2-8409cfe5e921afadeb490dbea39e6221_720w.webp)

同步异步：关注的是消息的通知机制*

阻塞非阻塞：关注的是在收到结果之前调用者的状态是等待还是忙自己的事情*

### 3.6.IO多路复用

- 还拿烧水的例子
- 不要你来管水开没开，直接交给一个代理，假如代理名叫select，select在那帮你监控水开没开，捎带他还会看饭有没有煮好，你把所有的事情都交代给它，可以去忙自己的事情了在饭还没熟，水还没开的时候select就处于一个等待的状态，假如这个时候水开了select会水开了的结果写到一个小黑板你可以看到并知道水开了，不需要你去查看水开没开，接下来由你将烧开的水灌进暖瓶（用户进程前半部分不阻塞，后半部份阻塞）

- ![img](https://pic3.zhimg.com/80/v2-3e3c6249511eb75bf6b026f8e5f52386_720w.webp)

### 3.7.select、poll、epoll的区别

无论是select、poll、epoll都可以面对多个用户进程的请求，它相当于一个代理人，收集很多用户进程的请求，他帮你从磁盘上获取数据，复制到内核中，那么这个数据准备没准备好它的实现机制是不一样的

通知方式：假设有一个用户数据准备好了，那么还有很多用户数据还没有准备好，那么如何通知？

select和poll是遍历扫描，效率低下

epoll采用回调机制，epoll会主动通知，效率更高（nginx支持）

### 3.8.信号驱动IO

- 举例：比如我们的智能热水壶我么设定好烧水以后，会给你一个反馈结果为设定成功，然后你就可以去忙其他的事情了，等到水烧开了会发给你一条短息，这个时候你再回去把水灌入暖瓶

- ![img](https://pic1.zhimg.com/80/v2-190efdab6bda949111ca47cec8a527bc_720w.webp)

- 通知机制：
  水平触发：多次通知
  边缘触发：只通知一次

- ![img](https://pic3.zhimg.com/80/v2-e94c61f777d1a25e4871637cb10332ce_720w.webp)

原文链接：https://zhuanlan.zhihu.com/p/283073309

作者：[Hu先生的Linux](https://www.zhihu.com/people/huhu520-10)