由《Unix网络编程卷1》总结而来。
1、I/O复用
同时监视多个I/O条件,在其中任意一个就绪时通知进程,这样的能力称为I/O复用。由select和poll函数支持,较新的还有Posix中的pselect函数。(Linux中还有epoll)。
I/O复用应用场合:
1)客户同时处理多个描述符时,必须使用I/O复用。
2)客户同时处理多个套接字时(比较少见)。
3)一个TCP服务器既要处理监听套接字,又要处理已连接套接字。
4)一个TCP服务器既要处理TCP,又要处理UDP。
5)一个TCP服务器要处理多个服务或多个协议。
2、I/O模型
Unix可用的5种I/O模型:
1)阻塞式I/O;
2)非阻塞I/O;
3)I/O复用(select和poll);
4)信号驱动式I/O(SIGIO);
5)异步I/O(Posix的aio_系列函数)。
一个输入操作一般包括两个阶段:
1)等待数据准备好
2)从内核向进程复制数据
2.1 阻塞式I/O模型
默认情形下,所有套接字都是阻塞的。
应用进程调用I/O操作时阻塞,只有等待要操作的数据准备好,并复制到应用进程的缓冲区中才返回,或者发生错误(系统调用被信号中断)返回。
2.2 非阻塞式I/O模型
当应用进程要调用的I/O操作导致阻塞时,也就是内核中的数据并没有准备好,直接返回一个错误!!!!;当已有数据准备好时,执行复制,并成功返回。
简言之,指在不能立刻得到结果之前,该函数不会阻塞当前进程,而会立刻返回。
一般情况下,应用进程需要利用轮询(polling)的方式来检测某个操作是否就绪。往往耗费大量的CPU时间。
2.3 I/O复用模型
阻塞发生在select/poll的系统调用上,而不是阻塞在实际的I/O系统调用上。select/poll发现有数据就绪后,通过实际的I/O操作将数据复制到应用进程的缓冲区中。
I/O复用与阻塞式I/O并不显得有什么优势,且由于使用select需要两个而不是一个系统调用,I/O复用还稍显劣势。不过,使用select的优势在于我们可以等待多个描述符就绪。
2.4 信号驱动式I/O模型
让内核在描述符就绪时发送SIGIO信号通知我们。
它的优势在于等待数据报到达期间进程不会被阻塞。
2.5 异步I/O模型
应用进程通知内核开始一个异步I/O操作,并让内核在整个操作(包含将数据从内核复制到应该进程的缓冲区)完成后通知应用进程。
原理:调用aio_read函数告诉内核在操作完成时如何通知我们,然后系统调用立即返回。并且在等待I/O完成期间,我们的进程不会被阻塞。操作完成时,内核会产生信号通知。
与信号I/O的区别是:信号I/O是内核通知何时可以启动一个操作,异步I/O是由内核通知我们I/O操作何时完成。!!!!完成后会产生指定的信号。
2.6 同步I/O和异步I/O对比
1)同步I/O操作导致请求进程阻塞,直到I/O操作完成;
2)异步I/O操作不导致请求进程阻塞。
前4种模型都是同步I/O模型,因为其中真正的I/O操作将阻塞进程。