class="MsoNormal">?
?
参考多路复用模型,各个信道类比是各个描述字(),高速信道即select函数
? 如果一个或多个IO条件满足(例如:输入已准备好被读,或者描述字可以进行输出时),我们就被通知到。这个能力被称为IO复用,是由select poll支持的。
?
多路复用模型:
首先,各个低速信道的信号通过多路复用器(MUX,多工器)组合成一路可以在高速信道传输的信号。在这个信号通过高速信道到达接收端之后,再由分路器(DEMUX,解多工器)将高速信道传输的信号转换成多个低速信道的信号,并且转发给对应的低速信道。[2]
?
?
阻塞IO
非阻塞IO
IO复用(select poll)
信号驱动IO(SIGIO)
异步IO(Posix.1的aio_系列函数)
?
一个输入操作一般有2个不同的阶段:
1 等待数据准备好
2 从内核到进程拷贝数据
?
?
?
recvfrom = receive from = 真正的IO操作 = 系统调用
进程调用recvfrom,此系统调用直到数据报到达且拷贝到应用缓冲区或出错才返回 . 最常见的错误是系统调用被信号中断。
? 这里进程的阻塞时间是指从调用recvfrom开始到它返回的这段时间,当进程返回成功指示时,应用进程开始处理数据。
(活动)阻塞:即进程不占用CPU,不再运行下去,但内存状态保留
?
?
这种模型只是偶尔才遇到,一般只有专门提供某种功能的系统中才有。
应用程序不断地调用recvfrom,请求内核来看看某种操作是否准备好,这对CPU时间是极大的浪费.
?
?
?
有了IO复用,就可以调用select或poll,在这2个系统调用中的某一个上阻塞,而不是阻塞于真正的IO系统调用. (即select包含有一个阻塞的队列)
Select的好处是:一个select可以同时处理多个描述字,而不是一个一个的等待。
(即:select是一个 阻塞队列的Manager)
?
?
?
信号驱动IO:让kernel 在描述字准备好的时候用SIGIO通知我们
?
?
当数据报准备好被读时,就为该进程生成一个SIGIO信号。然后随即可以在信号处理程序中调用recvfrom来读取数据报。(PS:此时recvfrom还是会阻塞,因为需要从内核内存中拷贝数据到应用程序的缓存区)
?
?
这种模型与信号驱动模型的主要区别在于:信号驱动IO是由内核通知程序何时可以启动一个IO操作,而异步IO模型是由内核通知我们IO操作何时完成.
?异步IO的信号是直到数据已拷贝到应用缓冲区才产生的,这一点于信号驱动IO模型不同。
?
PS: 信号驱动,都是需要中断 支持的
?
?
一个输入操作一般有2个不同的阶段:
1 等待数据准备好
2 从内核到进程拷贝数据
?
前4种模型的主要区别是第一阶段, 后2种模型的主要区别是第