前文
在同步与异步&阻塞与非阻塞中,简要的介绍一些基础概念,但这些概念最终是为IO所服务,是为文件所服务。按照Linux一句话来讲,一切皆文件。html
1、Unix IO模型
Unxi大师Richard Stevens在 UNIX® Network Programming 中讲述了五种I/O 模型java
- blocking IO
- nonblocking IO
- IO multiplexing
- signal driven IO
- asynchronous IO
而本文也是基于这五种I/O模型,以及交叉着同步与异步&阻塞与非阻塞的概念。但在探讨I/O模型以前,先要了解一下I/O模型发生的对象和步骤。linux
对于一个文件IO的操做(这里以read为例子),会涉及到两个对象:web
- 一个是调用这个IO的进程process
- 另一个就是系统内核kernel
当一个read操做发生时,会经历两个阶段app
- 进程等待内核数据准备(Waiting for the data to be ready)
- 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
2、五大I/O模型
1.blocking IO(阻塞IO)
1.1 概念介绍

在默认状况下,全部的IO操做都是blocking io,流程如上图所示,步骤为:异步
- 一、应用进程(application process) 调用了recvfrom这个系统调用
- 二、而后内核(kernel)开始了IO的第一个阶段:准备数据。在内核准备数据期间,应用进程是一直阻塞的。(Waiting for the data to be ready)
- 三、内核准备好数据以后,把数据从内核copy到应用内存。在内核copy数据期间,应用进程依然是一直阻塞的。(Copying the data from the kernel to the process)
- 四、内核返回结果,应用进程才解除block的状态,从新继续执行
1.2 场景比喻
又到了小明买奶茶的时候了。若是不知道小明买奶茶的故事,点这里socket
小明去买奶茶,可能会有两种方式:async
- 小明点单交钱,而后等着取奶茶;
- 小明点单交钱,而后奶茶妹给了小明一个小票,等小明的奶茶作好了,再告诉小明来取;
如今【小明点单交钱,而后等着取奶茶】升级一点情节,变成了以下方式:函数
- 小明点单交钱,而后等着奶茶妹作奶茶,等着奶茶妹把奶茶给他
这样就变成了这样:性能
- 对比blockingIO模型,小明就是应用进程(application process),奶茶妹就是内核(kernel)
- 小明点单交钱就是就是调用recvfrom
- 奶茶妹作奶茶,就是(Waiting for the data to be ready)
- 奶茶妹把奶茶给小明,就是(Copying the data from the kernel to the process)
1.3 blockingIO总结
blocking IO的特色就是在IO执行的两个阶段都阻塞了,而blocking IO整个过程也是同步模型,因此blocking IO能够叫作同步阻塞IO
2.non-blocking IO(非阻塞IO)
2.1 概念介绍

非阻塞IO与阻塞不一样点在于不断的查询数据是否准备好,如上图所示,流程为:
- 一、应用进程(application process) 调用了recvfrom这个系统调用
- 二、内核告诉应用进程,数据尚未准备好
- 三、应用进程发现数据没有准备好,不停的调用recvfrom这个系统调用,内核在数据没有准备好的状况下不停的告诉应用进程数据没有准备好。妈的智障
- 四、内核准备数据。这个过程当中,应用进程没有阻塞,由于它在不停的调用!(Waiting for the data to be ready)
- 五、在应用进程不停的调用中,刚好此次内核把数据准备好了,而后内核把数据copy到应用进程内存。在内核copy数据期间,应用进程是一直阻塞的。(Copying the data from the kernel to the process)
- 六、内核返回结果,应用进程解除block的状态,从新继续执行
2.2 场景比喻
如今【小明点单交钱,而后等着取奶茶】升级成了下面情节,变成了以下方式:
- 小明点单交钱,奶茶妹说我这就给你作奶茶,还没好,你等会。
- 不到3秒钟,小明就问奶茶好了没有,奶茶妹说尚未哦。又过了3秒钟小明又问奶茶好没有,奶茶妹说没有哦。
- 问了不知道多少次以后,奶茶妹此时终于作好了奶茶,而后把奶茶交到小明手里
- 奶茶妹说了一句,你的奶茶好了,滚!
2.3 总结
nonBlocking IO模型中,数据准备阶段并无阻塞,由于应用进程不断的查询内核数据是否准备完毕,并无被阻塞,实际上应用进程能够在这时干其余事情。在数据复制阶段阻塞。
non-blocking IO模型就不能理解为同步非阻塞模式了,可是也不能理解为异步非阻塞模式,算是同步和异步的一个混合体。
3. IO multiplexing(多路复用)
3.1 概念介绍

多路复用听上去比较难理解,但对应linux的select,poll就好理解了,如上图所示,流程为:
- 一、应用进程(application process) 调用了select这个系统调用
- 二、内核开始准备数据。在内核准备数据期间,应用进程是一直阻塞的。(Waiting for the data to be ready)
- 三、内核告诉应用进程数据准备好了
- 四、应用进程(application process) 调用了recvfrom这个系统调用
- 五、内核把数据copy到应用进程内存。在内核copy数据期间,应用进程是一直阻塞的。(Copying the data from the kernel to the process)
- 六、内核返回结果,应用进程解除block的状态,从新继续执行
咋一看,咦,好像和blockingIO差很少,并且还多了一步调用。那优缺点在哪里呢?
- 当用户进程调用了select,内核监视这个IO请求
- 当N个用户进程调用了select,内核监视N个IO请求
- 有一个用户进程的IO数据准备好了,内核告诉该用户进程数据准备好了,来取吧
- 因此优势就在于内核能够多监视更多的IO请求,能够同时处理多个connection(多说一句。因此,若是处理的链接数不是很高的话,使用select/epoll的web server不必定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优点并非对于单个链接能处理得更快,而是在于能处理更多的链接。)
- 在IO multiplexing Model中,如上图所示,整个用户的process实际上是一直被block的,只不过process是被select这个函数block,而不是被socket IO请求给block。这句很重要。
- 实际中,对于每个socket,通常都设置成为non-blocking,轮训的时机设计好,才能体现出该IO设计模型的优点。
3.2 场景比喻
如今【小明点单交钱,而后等着取奶茶】升级成了下面情节,变成了以下方式:
- 小明点单交钱
- 而后奶茶妹开始作奶茶
- 奶茶妹作好奶茶以后,告诉小明过来取奶茶
- 小明取奶茶
- 奶茶妹把奶茶交到小明手里
- 小明离开
3.3总结
IO multiplexing优势在于内核能够处理多个IO请求。通常会运用非阻塞IO和IO multiplexing进行组合。
4. signal driven I/O(信号IO)
4.1 概念介绍

信号模型比较简单,以下流程:
- 应用进程发起一个信号,告诉内核说我须要什么文件,而后立马返回
- 内核准备数据。应用进程该干吗干吗,不会阻塞。
- 内核准备好数据,告诉应用进程来取数据
- 应用进程请求取数据
- 内核把数据复制到应用进程。应用进程阻塞。
- 返回数据
4.2 场景比喻
如今【小明点单交钱,而后等着取奶茶】升级成了下面情节,变成了以下方式:
- 小明点单交钱,奶茶妹给小明一个小票
- 而后奶茶妹开始作奶茶
- 奶茶妹作好奶茶以后,告诉小明过来取奶茶
- 小明取奶茶
- 奶茶妹把奶茶交到小明手里
- 小明离开
4.3 总结
信号驱动IO模型,就能够为异步阻塞IO模型。
5. asynchronous I/O(异步非阻塞)
5.1 概念介绍

流程以下:
- 应用进程发起一个信号,告诉内核说我须要什么文件,而后立马返回
- 内核准备数据。应用进程该干吗干吗,不会阻塞。
- 内核把数据copy到应用进程内存。应用进程该干吗干吗,不会阻塞。
- 返回数据
有没有碉堡了的感受,linux aio就是这种模型
5.2 场景比喻
如今【小明点单交钱,而后等着取奶茶】升级成了下面情节,变成了以下方式:
- 小明点单交钱,奶茶妹给小明一个小票
- 而后奶茶妹开始作奶茶
- 奶茶妹作好奶茶以后,把奶茶递到小明手里。次奥这么好待遇
- 小明拿到奶茶,小明离开
5.3 总结
异步非阻塞IO,应用进程两个阶段都不会阻塞。简直完美。
3、大总结
- blocking I/O,数据准备、数据copy 全阻塞,同步阻塞IO
- nonblocking I/O,数据准备不阻塞,数据copy阻塞,非阻塞IO
- I/O multiplexing,数据准备阻塞,数据copy阻塞,多路复用IO,优势能够支持更多IO请求
- signal driven I/O (SIGIO),数据准备不阻塞,数据copy阻塞,异步阻塞IO
- asynchronous I/O,数据准备、数据copy 所有阻塞。异步非阻塞IO
#文章引用 I/O Models