Richard Stevens的《UNIX? Network Programming Volume 1, Third Edition: The Sockets Networking 》6.2节“I/O Models ”中详细说明了网络编程中的五种I/O模型:blocking IO、nonblocking IO、IO multiplexing、signal driven IO和asynchronous IO。这里将简单介绍一下这五种模型。
网络I/O
一般地,一个基本的IO会涉及到两个系统对象:一个是调用这个IO的进程对象,另一个就是系统内核(kernel)。当一个网络read操作发生时,将会发生如下过程:
- 通过read系统调用向内核发起读请求
- 内核向硬件发出读指令,并等待读就绪
- 内核把要读取的数据复制到描述符所指向的内核缓存区
- 数据从内核缓存区拷贝到用户进程空间
这个过程可分为等待数据准备好和将数据从内核拷贝到进程两个阶段。
五种模型
- 阻塞I/O模型:默认情况下所有文件操作都是阻塞的。用户进程发出读操作系统调用后,如果等待数据准备好并从内核拷贝到用户空间,则系统调用返回;否则,进程被阻塞,直到数据准备好并从内核拷贝到用户空间,才唤醒用户进程使用用户进程重新执行。
- 非阻塞I/O模型:用户进程发出读操作系统调用后,如果等待数据准备好并从内核拷贝到用户空间,则系统调用返回;否则,返回错误。整个过程用户进程不会被阻塞。
- 信号驱动I/O模型:用户进程注册I/O消息息处理函数并继续执行。内核数据准备好后会发出SIGIO通知,用户进程I/O消息处理函数发出可阻塞读操作系统调用。
- 异步I/O模型:用户进程发出读操作系统调用后直接返回。Kernel在执行完两个阶段的工作将数据放入进程空间后发出消息给用户进程。
- I/O多路复用:进程处理多请求时的I/O方式。用户进程将所有请求绑定到同一select/poll/epoll上,用户进程发出select/poll/epoll系统调用后阻塞,直到某些请求的数据准备好返回。然后对准备后的请求依次调用可阻塞读操作。
I/O模型 | 等待数据准备好 | 从内核拷贝到进程 | 优点 | 缺点 |
阻塞I/O模型 | 阻塞 | 阻塞 | 能及时返回数据,内核开发简单 | 需要进程等待,无法处理多任务 |
非阻塞I/O模型 | 非阻塞 | 非阻塞 | 无需进程等待,可处理多任务 | 任务响应延迟大,整体数据吞吐量降低 |
信号驱动I/O模型 | 非阻塞 | 阻塞 | 很好的平衡任务响应和多任务处理 | 需要注册信号处理函数,开发不方便 |
异步I/O模型 | 非阻塞 | 非阻塞 | 任务响应及时且可处理多任务 | API接口和应用开发都不方便 |
I/O多路复用 | 阻塞/非阻塞 | 阻塞 | 可同时处理多个连接请求 | 单连接请求效率低 |
参考
http://noican.blog.51cto.com/4081966/1354950