直到客户端检测不到EOF。这个时候需要进程有一种能力。
这个能力:发现一旦一个多个I/O通道(网络,操作系统)就绪。它就会通知进程。
这个能力就是I/O复用! 一般由select 和 poll 这两个函数支持。还有一个函数pselect。
有几个场景需要应用到这个能力:
1 当客户处理 多个描述符。(处理交互输入 和 网络套接字) (不同描述符 )
2 一个客户处理多个 网络套接字 。 (不同地址套接字)
3 如果一个TCP服务器既要处理监听套接字,又要处理连接套接字。(不同类型套接字)
4 一个服务器同时处理tcp udp。一般也要用 I/O 复用了。(不同协议套接字)
5 一个处理器处理多个服务或者多个协议。(不同地址/端口套接字)
Linux 有5种I/O模型:
1 阻塞式IO
2 非阻塞式IO
3 IO复用
4 信号驱动式IO
5 异步IO
但是万变不离其中,本质上都是输入操作,1等待数据准备好 2从内核向进程复制数据
网络方面则是异曲同工,1等待网络数据到操作系统 2内核把它们分组存在内核缓冲区 3把内核缓冲区数据往进程缓冲区复制
1 阻塞式IO
2非阻塞式I/O
这种就是不断地调用recvfrom 让进程轮询内核,以查看操作就绪没?这么做往往耗费大量CPU资源。
3 I/O复用模型
与前两个比起来好像没有什么优势一样。但它真正的优势是可以等待多个描述符就绪。
4信号驱动式IO模型
主要优势就是 主程序不需要被阻塞。可以把recvfrom分离出主循环里。
5异步IO模型
和前面信号驱动IO有区别。区别在于发出信号的时机。前面那个是数据准备好就发送信号。
这个则是数据准备好,复制给进程缓冲区完成后才发送信号。这个优势在于一点都不需要阻塞。
前一个信号驱动型的 有时间损耗(等待数据复制给进程)所以还是需要阻塞一下的。
这个完全不需要阻塞。等待数据到了进程缓冲区才发送信号!!
5种模型对比:
只有第五种才是真正的异步IO.(符合POSIX定义)
select函数: