五种IO模型


  • IO的基本操作

    IO通常涉及两个步骤:

    1. 等待数据准备就绪
    2. 将数据从内核中复制到进程中

    阻塞式IO

    进程发出recvfrom这个系统调用,进入阻塞状态,直到数据准备就绪并复制到我们的应用缓冲区中.阻塞式IO的特点是IO涉及的两个阶段中,进程都是阻塞的

    img

    非阻塞式IO

    进程轮询发出recvfrom这个系统调用,如果数据没有准备好,系统返回一个错误信息,如果数据准备好,则将数据从内核复制到我们的应用缓冲区中.非阻塞式IO的特点是一阶段进程是非阻塞的,二阶段进程是阻塞的.

    img

    IO多路复用

    进程执行select/epoll来监听多个文件描述符,此时进程进入阻塞状态.如果有其中一个文件描述符可读,那么select/epoll就会返回.接着进程向可读的文件发出recvfrom系统调用,进入阻塞状态,将数据从内核复制到我们的应用缓冲区中.IO多路复用的特点是一阶段是阻塞的,但是可以监听多个文件描述符,一旦监听到有数据产生,我们可以选择是否进入二阶段,如果进入二阶段,那么进程将进入阻塞状态.

img

信号驱动IO

进程注册一个信号处理器并发出一个sigaction系统调用,内核接收到这个调用后返回,这个过程是非阻塞的.当数据准备就绪,内核发出一个 SIGIO信号到我们的信号处理器来告知数据准备就绪.接着进程发出一个recvfrom系统调用,进入阻塞状态,等待数据从内核复制到我们的应用缓冲区中,或者也可以让信号处理器发出一个recvfrom系统调用,将数据从内核复制到我们的应用缓冲区中,之后通知进程来读取数据.这个模型的优点是我们不必等待数据就绪,而是等待收到一个信号,再决定是否进入阻塞状态去获取数据.

img

异步IO

进程向内核发出一个aio_read调用,并告诉内核如何通知我们,这个过程不会发生阻塞.当数据从内核复制到我们的应用缓冲区完成后,内核再通知我们处理数据.信号驱动IO和异步IO的区别是:前者是数据可以准备读取了通知进程,后者是数据读取完成了通知进程.

img

五种IO模型的比较

img

五种IO模型中,前四个模型的二阶段都是阻塞的.

同步IO和异步IO

同步IO意味着进程在请求IO时可能发生阻塞,异步IO意味着进程在请求IO时不会发生阻塞,除了异步IO全流程不会发生阻塞,所以是异步IO.其它IO模型进行IO调用(recvfrom调用)都会发生阻塞,所以是同步IO.

参考资料

Unix网络编程卷1 6.2 I/O Models


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!