您好,欢迎来到华拓科技网。
搜索
您的当前位置:首页【Linux系统】文件内核级缓冲区的概念与使用

【Linux系统】文件内核级缓冲区的概念与使用

来源:华拓科技网






文件内核缓冲区


在文件结构体 struct file 的内部,存在一个用于存储临时数据的内核缓冲区的数据结构,该内核缓冲区和文件结构体 struct file 中的 address_space 字段有关(这里暂时不具体讲解)。该缓冲区对于优化读写操作至关重要,这就是常说的 文件内核级缓冲区。


通过系统调用 write 写入文件


写入的详细过程:

当进程执行类似 write(3, "hello", ...) 这样的指令时,系统首先根据文件描述符(本例中为3)查找对应的文件描述符表项,并从中获取指向 struct file 结构体的指针。随后,待写入的数据(如字符串"hello")会被拷贝到该 struct file 结构中的内核缓冲区。接着,将调用与目标设备相关的写入函数,这些函数通常位于 file_operations 操作表中。最终,通过刷新内核缓冲区的方式,将数据实际写入对应的文件。

内核到磁盘的拷贝由系统决定:我们使用系统调用 write 将数据从用户空间主动拷贝到文件的内核级缓冲区。至于何时将文件内核级缓冲区的内容真正刷新到磁盘文件中,则由操作系统依据其内置的策略和条件自动控制决定。

因此,写入文件内容的过程遵循如下路径:用户层 —> 内核的数据结构 struct file 的缓冲区 —> 磁盘文件。这说明了我们在进行文档编辑等操作时,本质上是在将用户输入的数据拷贝至内核的缓冲区中。

Ctrl+s用于主动刷新:关于保存动作(例如按下 Ctrl+s),它实际上是用户主动触发内核缓冲区内容刷新的过程(前面不是说内核缓冲区中的刷新由系统决定吗, Ctrl+s 相当于主动刷新),确保最新修改被安全地保存到外部存储设备上。


通过系统调用 read 读取文件


读取:当通过系统调用 read 读取文件时,会先在文件内核缓冲器读取数据,当该数据内容不在缓冲器时,则会调用更为底层的该设备对应的 struct device 中的函数 read_disk,将磁盘的文件内容读取拷贝到文件内核缓冲区,这一步的拷贝往往需要一些时间,上层就需要等待


系统调用接口 read 和 write 本质上都是一种拷贝型接口:

  • 读取时会将数据从外设拷贝到文件内核缓冲区(再从文件缓冲区拷贝到用户层缓冲区,进一步的读取);
  • 写入时会将数据从文件缓冲区拷贝到外设

为什么 scanf 获取键盘数据时会阻塞住:本质上是等待键盘设备数据响应,因为对应设备结构体的缓冲器没有想要的数据


修改文件的过程:系统将磁盘中文件这部分内容读取拷贝到文件内核缓冲区,用户通过系统调用 read将缓冲区的数据读取拷贝到用户层,在用户层对该文件内容进行修改,然后再写入拷贝到缓冲区,然后由系统决定将该修改后的数据拷贝会到磁盘的文件部分

本质上就是:先读取,再写入的过程



缓冲区存在的意义

  • 解决速度差异问题:由于直接I/O交互双方的速度不匹配(如CPU和磁盘之间的巨大速度差距),引入内存作为缓冲区能够提高速度较快一方(如CPU)的利用率。
  • 性能优化:频繁地将数据从内存写入磁盘会导致性能下降。通过缓存数据于内存中,可以减少磁盘 I/O 次数,从而提升应用程序的响应速度。

缓冲区的作用类似于物流中心,比如菜鸟驿站。当你寄送包裹时,你可以迅速将包裹交给驿站,而无需等待每件包裹都被立即发往目的地。类似地,操作系统可以在适当的时候批量处理并写入数据,而不是每次有新数据到来时都立即执行磁盘写入操作。


自动刷新机制


尽管内核具备自动刷新缓冲区的功能,但这一过程通常是异步且非即时的:
  • 定时刷新:内核会按照预设的时间间隔定期检查并刷新缓冲区数据至磁盘。
  • 基于容量的刷新:一旦内核缓冲区的数据量达到设定阈值,系统会自动启动数据写入磁盘的操作。
  • 文件关闭时刷新:当程序结束对文件的操作并调用 fclose 或者相应接口关闭文件时,操作系统会确保所有暂存于缓冲区的数据都被正确写入磁盘。



[综合理解] 记事本打字并保存的底层操作

通过解释记事本编辑器的原理,来进一步理解上面文章讲解的文件内核缓冲区等知识。

使用记事本打字并保存操作的底层步骤如下:

1、打字写入:启动一个编辑器页面,该页面会监听标准输入流 stdin(通常是键盘输入),每次你按下键盘上的键,相应的字符就会被操作系统捕获,并暂时存储在键盘对应的文件内核缓冲区中。接着,该编辑器页面进程就会主动从标准输入 stdin 的缓冲区中读取所有已有数据到编辑器页面进程自己的内存缓冲区中(也就是文件描述符 fd = 0 的文件:默认对应的该键盘文件结构体)

2、回显:编辑器页面进程会将自己内存缓冲区中的数据回显到显示器上,让用户可以看到当前打字的效果(也就是将缓冲区中的数据输入给 文件描述符 fd = 1 的文件结构体(默认对应显示器))

3、初步保存:上面的步骤都是在内存层面的初步数据接收,还未永久保存在文件中,当应用程序认为需要将数据写入文件时,它会调用标准库函数(如 fwrite),这些函数最终会触发系统调用(如 write),将进程的内存缓冲区中的数据拷贝到需要保存文件的文件结构体中的文件内核级缓冲区中。

4、永久保存:虽然数据已经被写入到内核缓冲区,但这还不足以保证数据已经安全地存储到了磁盘上。为了确保数据的安全性,操作系统会在适当的时机(比如缓冲区满、特定时间间隔或手动请求同步)调用“刷新”或“同步”机制,将内核缓冲区中的数据实际写入到持久化存储介质(如硬盘)。这个过程可能涉及到多个步骤,包括但不限于将数据从缓冲区转移到磁盘控制器,再由磁盘控制器执行物理写入操作。



因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo6.cn 版权所有 赣ICP备2024042791号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务