五种IO模型
一.同步阻塞
模型特点:
在Linux中,对于- -次读取I0的操作,数据并不会直接拷贝到程序的程序缓冲区。通常包括两个不同阶段:
a.等待数据准备好, 到达内核缓冲区;
b.从内核向进程复制数据。 对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所有等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。
故事描述
小明从家里面先到演唱会现场问售票业务员买票,但是票还没出来,
三天以后才出来,小明直接打了个地铺睡在举办商售票大厅,一直等票出来,然后买票。
主要网络模型:BIO
二.同步非阻塞
模型特点:
与阻塞式I/O不同的是,非阻塞的recvform系统调用调用之后,进程并没有被阻塞,内核马上返回给进程,如果数据还没准备好,此时会返回一个error (EAGAIN或EWOULDBLOCK)。进程在返回之后,可以处理其他的业务逻辑,过会儿再发起recvform系统调用。采用轮询的方式检查内核数据,直到数据准备好。再拷贝数据到进程,进行数据处理。在linux下,可以通过设置socket套接字选项使其变为非阻塞。
故事描述:
小明从家里面先到演唱会现场问售票业务员买票,但是票还没出来,然后小明走了,办理其他事情去了,然后过了2个小时,又去举办商售票大厅买票来了,如果票还没有出来,小明又先去办其他事情了,等两个小时再来看有没有票,直到买到票.
三.I/O复用(事件驱动)
模型特点
I0多路复用的好处就在于单个进程就可以同时处理多个网络连接的I0。它的基本原理就是不再由应用程序自己监视连接,取而代之由内核替应用程序监视文件描述符。以select为例,当用户进程调用了select,那么整个进程会被阻塞,而同时,kernel 会"监视”所有select负责的socket,当任何一个socket中的数据准备好了,select 就会返回。这个时候用户进程再调用read操作,将数
据从内核拷贝到用户进程.
故事描述:
小明想买票看演唱会,就直接给黄牛(selector/epolI)打电话了,说帮我留意买个票,买了通知我,我自己去取(当我接到黄牛的电话时,我需要花费整个路成的时间去读这个数据,买拿这个票) ,那么票没出来之前,小明完全可以做自己的事情。
主要网络模型:NIO
四.信号IO
模型特点:
允许Socket进行信号驱动I0,并注册一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到-一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。
故事描述:
小明想买票看演唱会,给举办商售票业务员说,给给你留个电话,有票了请你给我打个电话通知一下(是看人家操作系统提不提供这种功能,Linux 提供,windows没有这种机制),我自己再来买票(小明完全可以做自己的事情,但是票还是需要小明自己去拿的)。
五.异步非阻塞
模型特点:
上述四种I0模型都是同步的。相对于同步I0,异步I0不是顺序执行。用户进程进行aio_ read系统调用之后,就可以去处理其他的逻辑了,无论内核数据是否准备好,都会直接返回给用户进程,不会对进程造成阻塞。等到数据准备好了,内核直接复制数据到进程空间,然后从内核向进程发送通知,此时数据已经在用户空间了,可以对数据进行处理了。
故事描述:
小明想买票看演唱会给举办商售票业务员说(异步非阻塞i/o)打电话了,给你留个地址,有票了请通知快递员,把这张票送到这个地址来,当小明听到敲门门声,看见快递员,就知道票好了,而且知道票好了的时候,票已经到他手上了,票不用小明自己去取(应用不用自己再去read数据了)。
主要网络模型:AIO