Linux网路编程系列-网络I/O模型

应用程序从网络中拿数据,要经历两个阶段:1、等待数据准备好-分组到达,被拷贝到内核缓冲区,组装数据报;2、数据从内核缓冲区拷贝至用户态应用程序的缓冲区。Unix下五个I/O模型:

 阻塞I/O:

进程调用recvfrom,此系统调用直到数据报到达且拷贝到应用缓冲区(或出错)才返回。


非阻塞I/O:

应用程序调用recvfrom时无数据,内核立马返回错误;有数据,则拷贝数据到应用缓冲区。一般应用程序会循环调用recvfrom(轮询),不断查询内核数据是否准备好,浪费CPU。


I/O复用(select/poll/epoll,IO条件满足时获得通知):

应用阻塞于select调用,等待数据报可读。当select返回套接口可读条件时,我们调用recvfrom将数据拷贝到应用缓冲区。I/O复用对阻塞IO的好处是可以等待多个描述字准备好


信号驱动I/O(SIGIO):

通过系统调用sigaction安装一个信号处理程序(注册信号),然后立即返回。数据报准备好时,内核生成SIGIO信号通知信号处理程序,信号处理程序调用recvfrom取回数据或者通知主循环自己来取数据。好处:半阻塞,数据到达之前,程序不阻塞,主循环可以继续执行,只是等待信号处理程序的通知(数据准备好或者数据报准备好读)。


异步I/O(Posix.1的aio_和lio_系列函数):

与信号驱动模型的区别-信号驱动IO是由内核通知何时可以启动一个IO操作,而异步IO模型是由内核通知IO操作何时完成。我们调用aio_read函数告诉内核描述字、缓冲区指针、缓冲区大小、文件偏移,并告诉内核整个操作完成时何时通知我们。此系统调用立即返回,进程不阻塞于等待IO完成。

异步IO很少使用,支持的系统较少。


I/O模型对比:

前4种I/O模型主要区别在第一阶段,第二个阶段基本相同(在数据从内核拷贝到应用程序缓冲区时,进程阻塞于recvfrom调用)。而异步I/O的两个阶段都不同于前4个模型。


同步I/O与异步I/O定义(Posix.1)比较:

同步I/O:同步I/O操作引起请求进程阻塞,直到I/O操作完成。前四个模型阻塞I/O、非阻塞I/O、I/O复用模型和信号驱动型I/O模型都是同步I/O模型。

异步I/O:异步I/O操作不引起请求进程阻塞,因此只有两阶段都不阻塞的异步模型属于异步I/O。

 

posted @ 2014-05-14 09:49  春文秋武  阅读(159)  评论(0编辑  收藏  举报