计算机操作系统学习笔记(10)——文件IO

简介: 计算机操作系统学习笔记(10)——文件IO

⽂件的读写⽅式各有千秋,对于⽂件的 I/O 分类也⾮常多,常⻅的有

缓冲与⾮缓冲 I/O

直接与⾮直接 I/O

阻塞与⾮阻塞 I/O VS 同步与异步 I/O


一、缓冲与⾮缓冲 I/O

⽂件操作的标准库是可以实现数据的缓存,那么根据「是否利⽤标准库缓冲」,可以把⽂件I/O 分为缓冲 I/O 和⾮缓冲 I/O:

缓冲 I/O,利⽤的是标准库的缓存实现⽂件的加速访问,⽽标准库再通过系统调⽤访问⽂件。

⾮缓冲 I/O,直接通过系统调⽤访问⽂件,不经过标准库缓存。

⽐⽅说,很多程序遇到换⾏时才真正输出,⽽换⾏前的内容,其实就是被标准库暂时缓存了起来,这样做的⽬的是,减少系统调⽤的次数,毕竟系统调⽤是有 CPU 上下⽂切换的开销的。


二、直接与⾮直接 I/O

Linux 内核为了减少磁盘 I/O 次数,在系统调⽤后,会把⽤户数据拷⻉到内核中缓存起来,这个内核缓存空间也就是「⻚缓存」,只有当缓存满⾜某些条件的时候,才发起磁盘 I/O 的请求。

那么,根据「是否利⽤操作系统的缓存」,可以把⽂件 I/O 分为直接 I/O 与⾮直接 I/O:

直接 I/O,不会发⽣内核缓存和⽤户程序之间数据复制,⽽是直接经过⽂件系统访问磁盘。

⾮直接 I/O,读操作时,数据从内核缓存中拷⻉给⽤户程序,写操作时,数据从⽤户程序拷⻉给内核缓存,再由内核决定什么时候写⼊数据到磁盘。

说白了就是根据发生不发生内核缓存和⽤户程序之间数据复制来区别

如果你在使⽤⽂件操作类的系统调⽤函数时,指定了 O_DIRECT 标志,则表示使⽤直接I/O。如果没有设置过,默认使⽤的是⾮直接 I/O。


二、阻塞与⾮阻塞 I/O VS 同步与异步 I/O

I/O 是分为两个过程的:


1.数据准备的过程

2.数据从内核空间拷⻉到⽤户进程缓冲区的过程

阻塞IO

阻塞 I/O,当⽤户程序执⾏ read ,线程会被阻塞,⼀直等到内核数据准备好,并把数据从内核缓冲区拷⻉到应⽤程序的缓冲区中,当拷⻉过程完成, read 才会返回。

da402bbccc06439d8d54c7cb328b27fe.png

注意,阻塞等待的是「内核数据准备好」和「数据从内核态拷⻉到⽤户态」这两个过程。


⾮阻塞 I/O

⾮阻塞 I/O,⾮阻塞的 read 请求在数据未准备好的情况下⽴即返回,可以继续往下执⾏,此时应⽤程序不断轮询内核,直到数据准备好,但是获取数据的过程,是⼀个同步的过程,仍然需要等待的过程

293596abb04345c49d2a68adb5489416.png


IO多路复用

⾮阻塞 I/O中应⽤程序每次轮询内核的 I/O 是否准备好,感觉有点傻乎乎,因为轮询的过程中,应⽤程序啥也做不了,只是在循环。

为了解决这种傻乎乎轮询⽅式,于是 I/O 多路复⽤技术就出来了,如 select、poll,它是通过I/O 事件分发,当内核数据准备好时,再以事件通知应⽤程序进⾏操作。

487dfcb53e054341bfb7aaac44bb42b4.png

实际上,⽆论是阻塞 I/O、⾮阻塞 I/O,还是基于⾮阻塞 I/O 的多路复⽤都是同步调⽤。因为它们在 read 调⽤时,内核将数据从内核空间拷⻉到应⽤程序空间,过程都是需要等待的。

说白了就是他们第二步都是需要等待的


异步 I/O

⽽真正的异步 I/O 是「内核数据准备好」和「数据从内核态拷⻉到⽤户态」这两个过程都不⽤等待。

当我们发起 aio_read 之后,就⽴即返回,内核⾃动将数据从内核空间拷⻉到应⽤程序空间,这个拷⻉过程同样是异步的,内核⾃动完成的,和前⾯的同步操作不⼀样,应⽤程序并不需要主动发起拷⻉动作。


479bb76cd0804ce292be180c5ead12dc.png

总结

06f2c708045441dbbf8d8673159bc9cb.png


举个你去饭堂吃饭的例⼦,你好⽐⽤户程序,饭堂好⽐操作系统。

阻塞 I/O 好⽐,你去饭堂吃饭,但是饭堂的菜还没做好,然后你就⼀直在那⾥等啊等,等了

好⻓⼀段时间终于等到饭堂阿姨把菜端了出来(数据准备的过程),但是你还得继续等阿姨

把菜(内核空间)打到你的饭盒⾥(⽤户空间),经历完这两个过程,你才可以离开。


⾮阻塞 I/O 好⽐,你去了饭堂,问阿姨菜做好了没有,阿姨告诉你没,你就离开了,过⼏⼗

分钟,你⼜来饭堂问阿姨,阿姨说做好了,于是阿姨帮你把菜打到你的饭盒⾥,这个过程你

是得等待的。


基于⾮阻塞的 I/O 多路复⽤好⽐,你去饭堂吃饭,发现有⼀排窗⼝,饭堂阿姨告诉你这些窗

⼝都还没做好菜,等做好了再通知你,于是等啊等( select 调⽤中),过了⼀会阿姨通知

你菜做好了,但是不知道哪个窗⼝的菜做好了,你⾃⼰看吧。于是你只能⼀个⼀个窗⼝去确

认,后⾯发现 5 号窗⼝菜做好了,于是你让 5 号窗⼝的阿姨帮你打菜到饭盒⾥,这个打菜的

过程你是要等待的,虽然时间不⻓。打完菜后,你⾃然就可以离开了。


异步 I/O 好⽐,你让饭堂阿姨将菜做好并把菜打到饭盒⾥后,把饭盒送到你⾯前,整个过程

你都不需要任何等待。

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
目录
相关文章
|
25天前
|
存储 安全 固态存储
计算机启动:从插上电源到操作系统启动的全过程
当我们插上电源,计算机从休眠状态苏醒,直至操作系统完全启动,这一系列复杂的过程涉及到硬件和软件的多个层面。本文将详细解析计算机插上电源后操作系统所做的工作,揭示这一过程的技术细节。
36 6
|
24天前
|
Python
文件元数据获取方法对比:`os.path` 与 `os.stat`
本文对比了Python中两种获取文件元数据的方法:`os.path`和`os.stat`。通过示例代码展示了如何获取文件大小和修改时间,并从性能、功能性和代码可读性三方面进行了详细对比。最终给出了根据具体需求选择合适方法的最佳实践建议。
25 2
|
1月前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
2月前
|
搜索推荐 索引
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
44 2
|
2月前
|
编解码 Java 程序员
【文件IO】文件内容操作
【文件IO】文件内容操作
59 2
|
2月前
|
存储 Java API
【文件IO】文件系统操作
【文件IO】文件系统操作
52 1
|
3月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
245 12
|
2月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
42 0
|
2月前
|
存储 Java iOS开发
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
38 0
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。