I/O 五种 模型

五种 I/O 模型:

  • blocking I/O 阻塞 I/O
  • nonblocking I/O 非阻塞 I/O
  • I/O multiplexing (select and poll) I/O 多路复用( select 和 poll )
  • signal-driven I/O (SIGIO) 信号驱动 I/O ( SIGIO )
  • asynchronous I/O (the POSIX aio_ functions) 异步 I/O(POSIX aio_ 函数)

 输入操作通常有两个不同的阶段:

1.等待数据准备就绪。这涉及等待数据到达网络。当数据包到达时,它被复制到内核内的缓冲区中。

2.将数据从内核复制到进程。这意味着将(就绪的)数据从内核的缓冲区复制到我们的应用程序缓冲区中

blocking I/O

在上图中,进程调用 recvfrom 和系统调用不会返回,直到数据报到达并被复制到我们的应用程序缓冲区中,或者发生错误。最常见的错误是系统调用被信号打断,从调用 recvfrom 到返回,进程一直被阻止。成功返回后 recvfrom ,我们的应用程序将处理数据报。

nonblocking I/O

当套接字设置为非阻塞时,我们告诉内核“当我请求的 I/O 操作在不让进程进入睡眠状态的情况下无法完成时,不要让进程进入睡眠状态,而是返回错误”。图如下图:

对于前三个 recvfrom ,没有要返回的数据,内核会立即返回错误 EWOULDBLOCK 

当我们第四次调用 recvfrom 时,数据报已准备就绪,它被复制到我们的应用程序缓冲区中,并 recvfrom 成功返回。然后,我们处理数据。

当应用程序处于调用 recvfrom 非阻塞描述符的循环中时,它称为轮询。应用程序会不断轮询内核,以查看某些操作是否已准备就绪。这通常是浪费 CPU 时间,但偶尔会遇到这种模型,通常在专用于一个功能的系统上。

I/O multiplexing

使用 I/O 多路复用时,我们在这两个系统调用之一中调用 select or poll 和 block,而不是在实际的 I/O 系统调用中进行阻塞。下图是 I/O 多路复用模型的摘要

我们阻止对 select 的调用,等待数据报套接字可读。当 select 返回套接字是可读的时,我们调用 recvfrom 将数据报复制到我们的应用程序缓冲区中。

与阻塞 I/O 模型的比较

        缺点:使用 select 需要两个系统调用( select 和 recvfrom )而不是一个

        优点:我们可以等待多个描述符(数据)准备就绪

signal-driven I/O

信号驱动的 I/O 模型使用信号,告诉内核在描述符准备就绪时用 SIGIO 信号通知我们。图如下图:

我们首先启用信号驱动 I/O 的套接字,并使用 sigaction 系统调用安装信号处理程序。这个系统调用的回报是立即的,我们的过程仍在继续;它没有被阻止。

当数据报准备好读取时,就会为我们的过程生成 SIGIO 信号。我们可以:

        1.通过调用 recvfrom 从信号处理程序读取数据报,然后通知主循环数据已准备好处理

        2.通知主循环并让它读取数据报

这个模型的优点是,在等待数据报到达时,我们不会被阻塞。主循环可以继续执行,只需等待信号处理程序通知数据已准备好处理或数据报已准备好读取。

asynchronous I/O

异步 I/O 由 POSIX 规范定义,并且已经协调了各种标准中出现的实时函数的各种差异,这些差异共同构成了当前的 POSIX 规范。

这些函数的工作原理是告诉内核启动操作,并在整个操作(包括将数据从内核复制到缓冲区)完成时通知我们。此模型与信号驱动 I/O 模型之间的主要区别在于,对于信号驱动 I/O,内核会告诉我们何时可以启动 I/O 操作,但对于异步 I/O,内核会告诉我们 I/O 操作何时完成。例如,请参见下图:

我们调用 aio_read (POSIX 异步 I/O 函数以 aio_ or lio_ 开头)并向内核传递以下内容:

       1.描述符、缓冲区指针、缓冲区大小(相同的三个参数)、 read

        2.文件偏移量(类似于 lseek )

        3.以及如何在整个操作完成后通知我们。

此系统调用会立即返回,并且在等待 I/O 完成时,我们的进程不会被阻止。

在这个例子中,我们假设我们要求内核在操作完成时生成一些信号。在将数据复制到我们的应用程序缓冲区之前,不会生成此信号,这与信号驱动的 I/O 模型不同。

I/O 模型比较

下图是五种不同 I/O 模型的比较。

前四个模型之间的主要区别在于第一阶段,因为前四个模型中的第二阶段是相同的:当数据从内核复制到调用方的缓冲区时,进程在调用中被 recvfrom 阻止。但是,异步 I/O 处理这两个阶段,并且与前四个阶段不同

Synchronous I/O 与 Asynchronous I/O

同步I/O 和 异步I/O的如下定义:

同步 I/O 操作会导致请求进程被阻止,直到 I/O 操作完成。

异步 I/O 操作不会导致请求进程被阻止。

使用以上定义,前四个 I/O 模型(阻塞、非阻塞、I/O 多路复用和信号驱动 I/O)都是同步的,因为实际的 I/O 操作 ( recvfrom ) 会阻塞该过程。只有异步 I/O 模型与异步 I/O 定义匹配。

参考:https://litux.nl/mirror/unixnetworkprogramming/0131411551_ch06lev1sec2.html

Chapter 6. I/O Multiplexing: The select and poll Functions - Shichao's Notes

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值