8.IO模型
一.事件驱动模型
服务器处理模型程序,通常有以下几种:
(1)收到一个请求则创建一个新的进程来处理这个请求
(2)收到一个请求则创建一个新的线程来处理这个请求
(3)收到一个请求,把它放入事件列表,让主进程通过非阻塞IO的方式来处理请求(如图所示),python中的协程就是通过这种方式来处理的
非事件驱动和事件驱动的比较:
非事件驱动:在需要等待某个条件触发时,会不断的检查这个条件,直到条件满足,很浪费cpu
事件驱动:在等待某个条件触发时有机会释放cpu,进入睡眠状态,当事件触发时cpu会唤醒它,这样更加有效的使用cpu
二、IO多路复用
1.什么叫IO多路复用?看图说话,用心体会
2.阻塞IO,看图说话
(1)程序发出系统调用,程序阻塞等待系统回应(数据等待,阻塞状态)
(2)系统收到数据并且把数据从内核拷贝到用户区(数据拷贝,阻塞状态)
(3)程序收到系统回应继续运行
结论:等待数据和拷贝数据这两个阶段都是阻塞的
3.非阻塞IO,看图说话
(1)程序定时向系统发送数据请求(非阻塞,但是消耗cpu性能)
(2)系统收到数据并把数据从内核区拷贝到用户区(阻塞)
(3)程序收到系统回应继续运行
结论:在等待数据阶段,定时向系统询问是不是有数据,这个阶段不是阻塞的,但是很消耗cpu时间,另外一个弊端就是数据到达不是及时处理的,因为在询问中间有时间间隔,第二个阶段跟跟阻塞IO是一样的
4.IO多路复用,看图说话
(1)比较IO多路复用的图和阻塞IO的图,发现区别不大,只是中间多了一步
(2)对于单个连接来说,IO多路复用还比不上阻塞IO和非阻塞IO
(3)IO多路复用主要适用于多个连接,不适用于单个连接
5.异步IO
这个就牛逼了
对于前面提到的两个阻塞,在这里都不阻塞
6.区分两个概念
首先是阻塞和非阻塞:
阻塞就是程序进入休眠状态,不会继续往下执行,交出cpu使用权限,非阻塞则相反;
异步和同步:
程序运行过程中只要某个阶段出现阻塞状态就为同步,反之则是异步
7.IO多路复用的应用:select poll epoll
select
- 它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。
select目前几乎在所有的平台上支持
select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。
另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销。
poll
它和select在本质上没有多大差别,但是poll没有最大文件描述符数量的限制。
一般也不用它,相当于过渡阶段
epoll
直到Linux2.6才出现了由内核直接支持的实现方法,那就是epoll。被公认为Linux2.6下性能最好的多路I/O就绪通知方法。windows不支持
没有最大文件描述符数量的限制。 比如100个连接,有两个活跃了,epoll会告诉用户这两个两个活跃了,直接取就ok了,而select是循环一遍。
市面上上见到的所谓的异步IO,比如nginx、Tornado、等,我们叫它异步IO,实际上是IO多路复用。
posted on 2018-02-07 17:10 后端bug开发工程师 阅读(200) 评论(0) 编辑 收藏 举报