详解Linux文件中的数据是如何被写进磁盘

 更新时间:2024年05月15日 09:51:43   作者:春人.  
Linux 中,我们的每一个进程,打开的每一个文件都要有自己的 struct inode 对象和自己的文件页缓冲区(就是所谓的内核缓冲区),本文我们给大家介绍了Linux文件中的数据是如何被写进磁盘,需要的朋友可以参考下

一、操作系统对物理内存的管理

1.1 物理内存与磁盘的数据交换

物理内存与磁盘之间的数据交换一般是以 4KB(大小可改) 为单位进行的,其中物理内存中一个 4KB 大小的空间叫做页框,填入 4KB 内存中的内容叫做页帧。样做的好处有以下几点:

  • 减少 I/O 的次数,即减少 CPU 访问外设的次数以提高效率。一次访问 4KB 和分四次访问 1KB 相比,前者效率更高,因为前者 CPU 只和磁盘只打了一次交道,磁头和盘面只需要进行一次定位就可以读取出 4KB 的内容,而后者 CPU 和磁盘要打四次交到,并且这四次可能并不连续,意味着磁头和盘面要定位四次,大量的机械运动就伴随着效率的下降。

  • 基于局部性原理的预加载机制。即使当前 CPU 只需要访问100字节的内容,但操作系统和磁盘之间还是以 4KB 为单位将数据加载进来,一般认为,CPU 在访问当前磁盘中的代码和数据的时候,接下来有较大的可能性去访问附近空间的代码和数据。

小Tips:4KB 是科学家经过大量实现确定出来的一个较为合理的值。一个文件如果占用了多个数据块,那么只有最后一个数据块可能存在没用完浪费的情况。一个数据块只能被一个文件使用。加入有两个只有几个比特的小文件,那么会为他们俩一人分配一个数据块,他们两个不可能共享同一个数据块。

1.2 操作系统对物理内存的管理

首先操作系统一定是可以看到物理内存的。对物理内存的管理还是逃不脱先描述再组织,在内核中有一个 struct page 的结构体就是用来描述物理内存的,一个 struct page 对象就对应一个 4KB 的内存空间,该结构体里面记录了当前 4KB 的一些属性信息,例如:当前页框的状态,当前页框的引用计数等。操作系统将物理内存划分成一个个的 struct page 对象,然后用数组的形式组织起来,数组的下标就是对应的页号。随便给一个物理地址(一般一个物理地址对应一个字节)求它所在的页号,就是用该物理地址除以 (4KB*1024 = 4096字节)即可,也就是用该地址按位与上 0XFFFFF000,将低12位清零,就是该地址所在的页号。所有申请内存的动作都是在访问内存 page 数组,查看 struct page 里面的 flags 属性,通过 flags 属性判断当前页框的状态,得知该页框是否被使用,没被使用就去修改 flags,表示该页框已被申请。flags c除了可以表示当前页框是否被使用外,还可以用来表示该页框是只读的还是读写等状态。这里所说的操作系统对物理内存的管理只是一个雏形,真正的内存管理系统是非常复杂的,像伙伴系统算法、slab 分派器等。

二、再来看文件打开和写入

2.1 文件页缓冲区的引入

struct file 是内核中的一个数据结构,用来描述一个打开的文件。而 inode 是在介绍磁盘时引入的,磁盘上的一个文件对应一个 inode,它表示该文件的属性。struct file 和 inode 之间的关系是,struct file 中只记录了文件的少量属性,因此在内核中还有一个 struct inode 结构体专门用来记录一个文件的所有属性。在 struct file 中有一个指针字段指向该文件的 struct inode 对象。

而文件是包括内容加属性的,在磁盘上文件的属性用 inode 来存储,文件的内容用 block 来存储,上面说过在内核中用 struct inode 来存储文件属性,那一个文件的内容(数据)在内核中该如何表示呢?答案是采用文件页缓冲区。在 struct file 结构中有一个 struct address_space 字段的指针,该结构体里面有一个 struct radix_tree_root 结构体对象,这本质上是一个树状结构(基数数又或叫字典书),树中的每个节点都是 struct radix_tree_node 类型,该类型里面有一个名为 slots 的 void * 类型的数组,里面存的其实就是 struct page 对象的地址。总结一下就是在 struct file 结构体中有指向物理内存的指针,我们将这些物理内存就叫做文件页缓冲区。

2.2 向文件中写入的过程

在调用 C/C++ 库函数向文件中写入,首先将内容写入到语言层面的用户缓冲区,然后再在合适的时机将内容写入到该文件对应的文件页缓冲区中,最后再在合适的时机将内容写入到外设。将物理内存中的数据刷新到磁盘是由 I/O 子系统来执行,进程并不会关心,在操作系统中一定会存在非常多的 I/O 操作,可能会有很多进程都要将数据写入磁盘,操作系统会将所有的 I/O 操作根据先描述再组织的形式管理起来。内核中的 struct request 结构就是专门用来描述一个 I/O 操作的。为了提高 I/O 的效率,操作系统还会进行 I/O 排序和 I/O 合并,以减少磁头和盘面的定位次数。

总结:Linux 中,我们的每一个进程,打开的每一个文件都要有自己的 struct inode 对象和自己的文件页缓冲区(就是所谓的内核缓冲区)。

三、结语

以上就是详解Linux文件中的数据是如何被写进磁盘的详细内容,更多关于Linux文件数据写进磁盘的资料请关注脚本之家其它相关文章!

相关文章

  • linux系统用户管理与grep正则表达式示例教程

    linux系统用户管理与grep正则表达式示例教程

    这篇文章主要给大家介绍了关于linux系统用户管理与grep正则表达式的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用linux系统具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • Linux系统配置网络详细介绍

    Linux系统配置网络详细介绍

    大家好,本篇文章主要讲的是Linux系统配置网络详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • 使用 bind 设置 DNS 服务器的方法

    使用 bind 设置 DNS 服务器的方法

    Bind9是一个强大的Linux下开放源代码的DNS服务器软件,这篇文章主要介绍了使用 bind 设置 DNS 服务器的方法,需要的朋友可以参考下
    2020-03-03
  • CentOS8 配置本地yum源的详细教程

    CentOS8 配置本地yum源的详细教程

    centos8发行版通过 BaseOS 和应用流 (AppStream) 仓库发布,这篇文章主要介绍了CentOS8 配置本地yum源的详细教程,需要的朋友可以参考下
    2019-12-12
  • Linux创建文件的五种方法

    Linux创建文件的五种方法

    本文介绍五种在Linux系统中创建文件的方法,包括使用touch命令、使用文本编辑器创建文件、使用echo命令创建文件、使用cat命令创建文件以及使用重定向符号创建文件,全面了解并掌握在Linux系统中创建文件的各种常用方法,需要的朋友可以参考下
    2025-03-03
  • 教你一招实现Linux中的文本比对

    教你一招实现Linux中的文本比对

    这篇文章主要给阿加介绍了关于Linux下文本比对的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Linux使用fdisk进行磁盘的相关操作

    Linux使用fdisk进行磁盘的相关操作

    fdisk 命令是 Linux 中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下
    2025-01-01
  • Centos7的Firewalld防火墙基础命令详解

    Centos7的Firewalld防火墙基础命令详解

    这篇文章主要介绍了Centos7的Firewalld防火墙基础命令详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • ubuntu/deepin制作快捷启动图标的方法

    ubuntu/deepin制作快捷启动图标的方法

    这篇文章主要介绍了ubuntu/deepin制作快捷启动图标的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • 图文详解Linux服务器搭建JDK环境

    图文详解Linux服务器搭建JDK环境

    这篇文章主要以图文结合的方式详细介绍了Linux服务器搭建JDK环境的过程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10

最新评论