深入理解Unix下的五种I/O网络模型

Unix下的五种I/O网络模型分别为:

(1)阻塞式I/O
(2)非阻塞式I/O
(3)I/O多路复用
(4)信号驱动式I/O
(5)异步I/O


为什么会有这5种I/O模型?

明确两点:

  1. 网络I/O会涉及到两个系统对象:
    (1) 用户空间 调用的IO进程/线程
    (2) 内核空间 的内核系统

  2. I/O操作会经历两个阶段:
    (1) 等待数据准备就绪
    (2) 将数据从内核拷贝到进程或者线程

    上述两个步骤是针对read操作,如果是write,则I/O的两个阶段为:
    (1) 等待写缓冲区可写;
    (2) 将待写入的数据从进程或者线程拷贝到内核;

    针对在I/O操作的这两个阶段是否会发生阻塞,将I/O操作划分为5种模型。


“真正的I/O操作”:

将数据从内核空间拷贝到用户空间(recvfrom)和 将数据从用户空间拷贝到内核空间(sendto) 才是真正的I/O操作,等待数据就绪实际上并不是I/O操作,它只是在判断I/O是否可操作。

因此判断一个I/O模型是同步还是异步的标准就是 判断I/O操作时(recvfrom、sendto)是否将用户进程阻塞住。


同步与异步、阻塞与非阻塞:

同步、异步 描述的两个系统系统对象的关系(一个对象在操作I/O时是否会阻塞住另一个对象的执行,或者说一个对象是否会在另一个对象操作I/O时阻塞直至其操作完毕);

阻塞、非阻塞描述的是一个I/O的状态。


1. 阻塞式I/O:

阻塞式IO模型

阻塞式IO在【等待数据】和【拷贝数据】这两步都是阻塞的。


2. 非阻塞式I/O:

非阻塞式IO模型

非阻塞式IO在【等待数据】这一步是非阻塞的,在【拷贝数据】这一步是阻塞的,所以“非阻塞式IO”是一个伪的非阻塞形式,它在从内核将数据拷贝到用户空间的这一步中还是阻塞式操作的,异步IO才是真正的非阻塞。


3. I/O多路复用:

IO复用模型

进程阻塞在select函数上等待数据可读,当数据就绪后select返回,应用进程根据select返回的就绪fd的类型(可读、可写、出错)去调用对应的函数拷贝数据,拷贝数据的过程依然是阻塞式的。


4. 信号驱动式I/O:

信号驱动式IO模型

进程调用sigaction函数注册信号回调函数后就返回,因此在等待数据就绪这一步是非阻塞式的;当数据就绪后,内核调用之前注册号的信号回调函数,进程开始拷贝数据,这一步是阻塞的。


5. 异步I/O:

异步IO模型

【等待数据就绪】与【拷贝数据】这两步都是非阻塞的,当数据就绪后内核会自动将数据从内核空间拷贝的用户空间,拷贝完成后向用户进程发送一个信号,通知用户进程来读取数据。


5种I/O模型的比较:

5种IO模型的比较

前4种模型都是 同步I/O,因为 真正的I/O操作(recvfrom、sendto)将阻塞进程;
只有异步I/O模型与POSIX定义的异步I/O相匹配。

猜你喜欢

转载自blog.csdn.net/ArtAndLife/article/details/111398225