针对linux 操做系统的5类IO模型,阻塞式、非阻塞式、多路复用、信号驱动和异步IO进行整理,参考《linux网络编程》及相关网络资料。linux
阻塞模式编程
在socket编程(以下图)中调用以下四类函数致使阻塞:缓存
非阻塞模式服务器
针对上述四类阻塞模式的socket调用,都可经过设置的方式使其非阻塞。设置方式有两种fcntl设置套接字为O_NONBLOCK,以及ioctl设置FIONBIO。完成后其四类操做非阻塞,以下:网络
非阻塞模式在运用中采用轮询,或配合select的方式使用。异步
多路复用socket
进程定义读描述符集、写描述符集以及异常描述符集(做为select的入参),在select被调用时若是没有描述符集就绪,该select将被阻塞。当有任何一个或几个描述符就绪时,select设置描述符集,并返回就绪描述符的个数。函数
/*
* 多路复用select函数,参数定义以下
* nfds: select监视的文件句柄数,通常设置为最大文件号+1
* readfds:select监视的可读文件句柄集合
* writefds:select监视的可写文件句柄集合
* exceptfds:select监视的异常文件句柄集合
*/
int select(nfds, readfds, writefds, exceptfds, timeout)
注:对于监视一个描述符的状况,select与阻塞模式无区别。spa
信号驱动操作系统
信号驱动的方式属于一种异步的IO方式,进程自己不会被挂起,流程以下:
信号驱动的IO方式主要分如下三步操做:
signal(SIGIO,sig_handler); //设置SIGIO信号对应的处理函数 fcntl(sockfd,F_SETOWN, getpid());//设置接收SIGIO信号的进程为当前进程,该信号由sockfd句柄产生 ioctl(sockfd,FIOASYNC,&on);//容许sockfd套接字进行信号驱动的输入输出
对于UDP套接字,内核在如下状况下发送信号SIGIO:
对TCP套接字,内核在如下状况下发送信号SIGIO:
异步IO
异步IO是linux 2.6内核的标准特性,基本思想是容许进程发起不少IO操做,而不用阻塞或等待任何操做。稍后在接收到IO操做完成的通知时,再检索IO操做的结果。
aio过程的数据缓存在结构体aiocb中,该结构体定义以下:
struct aiocb { int aio_fildes; /* File desriptor. */ int aio_lio_opcode; /* Operation to be performed. */int aio_reqprio; /* Request priority offset. */ volatile void *aio_buf; /* Location of buffer. */ size_t aio_nbytes; /* Length of transfer. */struct sigevent aio_sigevent; /* Signal number and value. */
根据posix.1b所要求,主要包括以下函数: