做个家务,让我搞懂了 Linux I/O 模型

简介: 做个家务,让我搞懂了 Linux I/O 模型

I/O 其实就是 input 和 output(输入输出)

在计算机操作系统中对应数据流的输入与输出,在 Linux 中,既有文件的 I/O,也有网络 I/O

无论是文件 I/O 还是网络 I/O,其传输过程都是类似的

今天我们以文件 I/O 为例,来深入浅出一下 Linux 的 I/O 模型

我们的程序想要打开一个文件,去查看里面的内容,那么就需要将文件内容加载到内存里面,这个过程是一个比较复杂的过程

首先需要通过内核将数据从硬盘中读取出来,然后放到操作系统的内核缓冲区中,然后再将数据拷贝到程序缓冲区,这时候程序才能获取到相应的数据,打开相应的文件

简单来说,无论什么 I/O 模型,其读取过程都会经历下面两个阶段:

  • 将数据放到内核缓冲区(等待数据过程)
  • 将内核缓冲区的数据拷贝(copy)到程序缓冲区(拷贝数据过程)

image-20221212102411349.png
上面两个阶段完成之后,进程才能够对数据进行操作(读 or 写)

为了让大家能够更好的理解 Linux I/O 模型,咸鱼用囤了一个星期的臭衣服来作为例子(主要是懒)

一个轻松惬意的周六下午,咸鱼看着满满一篮子的臭衣服,痛定思痛,决定今天一定要把这堆衣服洗了

但是咸鱼家的洗衣机比较老旧,别人家的洗衣机都是洗涤甩干一条龙的,咸鱼家的洗衣机只能先洗涤,等洗涤完毕后咸鱼再去按甩干按钮进行衣服甩干(太惨了)

那么就将洗衣服可以分为两个阶段:

  • 按下洗涤按钮,洗衣机对衣服进行洗涤
  • 按下甩干按钮,洗衣机对衣服进行甩干

以上两个阶段均完成了之后,咸鱼才能把衣服拿去晾晒

阻塞 I/O

咸鱼在按下了洗衣机的洗涤按钮之后,就拿个小板凳在旁边干等着,在洗涤完衣服之前咸鱼啥事都不能干,只能乖乖地等洗衣机洗涤衣服

当洗衣机洗完衣服之后,咸鱼就按下甩干按钮,然后依旧坐在小板凳上干等着,直到洗衣机甩干好衣服为止

以上这两个阶段(洗涤和甩干阶段),咸鱼都处在一个阻塞的状态,他啥也干不了,只能乖乖地等洗衣机工作完

总结:

在阻塞 I/O 模型里面,将数据放到内核缓冲区(等待数据过程)以及将内核缓冲区的数据拷贝(copy)到程序缓冲区(拷贝数据过程),进程都是阻塞的

非阻塞 I/O

跟第一次不一样的是,咸鱼按下了洗衣机的洗涤按钮之后,他会不断地去打开洗衣机盖子,去看衣服洗好了没有

等洗衣机洗好了衣服之后,咸鱼按下洗衣机的甩干按钮,然后坐在小板凳上干等着,直到洗衣机甩干好衣服为止

以上这两个阶段(洗涤和甩干阶段),咸鱼都处在一个阻塞的状态,他啥也干不了,但是在第一阶段(洗涤阶段),咸鱼并没有干等着,而是不断地去查看洗衣机的状态——是否洗好衣服了

总结:

在非阻塞 I/O 模型里面,将数据放到内核缓冲区(等待数据过程)以及将内核缓冲区的数据拷贝(copy)到程序缓冲区(拷贝数据过程),都是阻塞的。

但比阻塞 I/O 有进步了一点,进程并不是站在那里干等,而是时不时跑去问一下内核。即使是无用功,效率多少还是提高了一点的

I/O复用

这一天,邻居家里有事外出了,但邻居也在洗衣服,于是邻居就拜托咸鱼帮忙看一下洗衣机

邻居家的洗衣机跟咸鱼家的洗衣机一样老旧,同样需要先洗涤后甩干

这个时候咸鱼就需要去不断地来回跑,先去看看自己家的洗衣机洗好衣服了没,然后再去看看邻居家洗衣机洗好衣服了没,接着再去看看自己家洗衣机洗好衣服了没

循环往复,直到看到某一台洗衣机完成洗涤

当咸鱼看到某一台洗衣机完成洗涤之后,就需要按下甩干按钮然后乖乖等衣服甩干

在洗涤阶段里面,咸鱼会不断地对洗衣机进行轮询查看,但依旧是阻塞的,因为咸鱼干不了其他事

在甩干阶段里,也是堵塞的,咸鱼只能乖乖地等洗衣机将衣服甩干

总结:

I/O复用模型的第二阶段与阻塞 I/O、非阻塞 I/O 的第二阶段是一致的(进程是堵塞的只能乖乖地将数据从内核缓冲区 copy 到程序缓冲区)

但是在第一阶段中,进程能够同时轮询多个数据流,监听多个数据流,其效率有巨大的提升

信号驱动 I/O

咸鱼发现,在小板凳上干等着多浪费时间啊,俗话说浪费时间无异于自杀,咸鱼决定在洗衣机洗涤阶段去干其他家务活,当洗衣机洗涤完毕后,会发出滴滴的声音,咸鱼听到这个声音之后就回来对衣服甩干

于是在洗涤阶段,咸鱼再也不用坐在小板凳上干等着,而是去拖地、烧水(干其他事)

当洗衣机洗涤完毕后,发出滴滴声音(信号),咸鱼听到这个声音之后就回来然后对衣服进行甩干

但是在甩干阶段咸鱼还是需要坐在小板凳上乖乖地等着

总结:

虽然说信号驱动 I/O 模型的第二阶段跟前面三个 I/O 模型一样,即进程是阻塞的。但在第一阶段做到了真正的异步

信号驱动 IO 在第一阶段,进程去请求内核读取数据,这时候其不会阻塞,也不会去轮询,而是设置一个信号回调。 当数据完全拷贝到系统内核时,系统发出 SIGIO 信号,通知进程去进行第二阶段,将数据拷贝到程序缓冲区

异步 I/O

聪明的咸鱼再次发现,既然我在洗涤阶段可以去干其他事,当我听到洗衣机洗涤完毕发出的滴滴声时我再回来进行甩干

那我为什么不能在甩干阶段也去干其他事情呢,当衣服甩干之后,洗衣机发出嘟嘟声,我听到嘟嘟声就知道甩干完毕了

于是在洗涤阶段和甩干阶段,咸鱼都不需要坐在小板凳上干等着,而是去干别的事情,当洗涤完毕或者甩干完毕的时候,洗衣机会发出滴滴或嘟嘟的声音

咸鱼听到声音就知道洗衣机洗涤或甩干完毕了,这时候他再过来处理衣服就行了

总结:

与信号驱动 I/O 类似,异步 I/O 模型在第一阶段通过信号回调的方式实现了进程的非阻塞

而在第二阶段,进程将数据从内核缓冲区 copy 到程序缓冲区的时候并非阻塞,而是同样设置一个信号回调,当 copy 完成后,进程收到通知,再去执行相应的操作

异步 IO 不仅仅是在第一阶段实现了信号回调,其也在第二阶段实现了信号回调,从而完全实现了异步 IO 操作

相关文章
|
5月前
|
缓存 安全 Linux
Linux 五种IO模型
Linux 五种IO模型
|
5月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第17天】重定向在Linux中改变命令I/O流向,默认有">"覆盖输出至文件及">>"追加输出至文件末尾,便于保存结果;使用"<"从文件读取输入而非键盘,高效处理数据。文件描述符如0(stdin)、1(stdout)、2(stderr)标识I/O资源,支持读写操作。管道以"|"连接命令,使前一命令输出成为后一命令输入,如排序用户或找出CPU占用最高的进程,构建复杂数据处理流程。
54 9
|
5月前
|
网络协议 Linux 数据安全/隐私保护
在Linux中,TCP/IP 的七层模型有哪些?
在Linux中,TCP/IP 的七层模型有哪些?
|
5月前
|
监控 Linux
在Linux中,如何监控磁盘I/O性能?
在Linux中,如何监控磁盘I/O性能?
|
5月前
|
Linux 数据安全/隐私保护
在Linux中,什么是文件权限?什么是rwx权限模型?
在Linux中,什么是文件权限?什么是rwx权限模型?
|
5月前
|
Linux 开发者
Linux源码阅读笔记18-插入模型及删除模块操作
Linux源码阅读笔记18-插入模型及删除模块操作
|
5月前
|
Linux
Linux的I/O操作
Linux的I/O操作
|
5月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第14天】输出重定向可将命令结果存入文件,如`>`覆盖写入或`>>`追加写入。输入重定向从文件读取数据,如`<`代替键盘输入。这些操作利用文件描述符(如0:stdin, 1:stdout, 2:stderr)管理I/O。管道`|`连接命令,使前一命令输出作为后一命令输入,便于数据处理,如排序用户`sort -t: -k3 -n /etc/passwd | head -3`或查找CPU占用高的进程`ps aux --sort=-%cpu | head -6`。
48 4
|
5月前
|
Unix Linux Shell
Linux I/O 重定向简介
Linux I/O 重定向简介
45 2
|
5月前
|
Linux 开发者
深入理解Linux I/O模型:同步、异步、阻塞与非阻塞
【8月更文挑战第1天】在探索操作系统的奥秘中,I/O模型作为影响性能的关键因素之一,常常让开发者们感到困惑。本文将通过浅显易懂的语言和实际代码示例,揭示Linux下同步与异步、阻塞与非阻塞的概念及其区别,并指导如何在实际应用中选择合适的I/O模型以优化程序性能。
172 1