文件读写的理论

文件读写的理论

大家好,又见面了,我是全栈君。

为了提高效率,略微复杂一些的操作系统对文件的读写都是带缓冲的,Linux当然也不例外。所谓缓冲,就是操作系统为近期刚读写的文件内容在内核保留一份副本,以便当再次须要已经缓冲存储在副本中的内容时就不必再暂时从设备上读入,而须要写的时候则能够先写到副本中,待系统较为空暇的时候再从副本写入设备。在多进程的系统中,因为同一个文件可能为多个进程所共享,缓冲的作用就更为显著。

然而,怎么样实现缓冲,在哪一个层次上实现缓冲,确实一个值得考虑的问题。

在文件层有三种基本的数据结构:file、dentry、inode。

先看file结构:前面讲过。一个file结构代表着目标文件的一个上下文,不但不同的进程能够在同一个文件上建立不同的上下文(每一个进程都有自己的file结构体),就是同一个进程也能够通过打开同一个文件多次而建立起多个上下文。假设在file结构中设置一个缓冲区队列,那么缓冲区中的内容尽管贴近这个特定上下文的使用者,却不便于为多个进程共享,甚至不便于同一个进程打开的不同上下文共享,这显然是不合适的。

那么dentry结构怎么样呢?这个数据结构并不属于某一个上下文,也不属于一个进程,能够为全部进程和上下文共享。但是dentry结构与目标文件并非一一相应的关系,通过文件链接,我们能够为已经存在的文件建立别名。一个dentry结构知识唯一的代表这文件系统中的一个节点,也就是一个路径名,但是多个节点能够同一时候代表同一个文件,所以还应该再抽象一次。

显然,在inode数据结构设置一个缓冲队列是最合适只是了,首先。inode结构与文件是一一相应的关系。即使一个文件有多个路径名。最后也归为同一个inode上。再说,一个文件里的内容是不能由其它文件共享的,在同一时间里,设备上的每个记录都仅仅能属于至多一个文件,将载有同一个文件内容的缓冲区都放在其所属文件的inode结构中是非常自然的事。因此在inode数据结构中设置了一个指针i_mapping,它就指向一个address_space数据结构。缓冲区队列就在这个数据结构中。

只是。挂在缓冲区队列中的并非记录块而是内存页面。也就说,文件的内容并非以记录块为单位。而是以页面为单位进行缓冲的。为什么这个搞?这是为了将文件内容的缓冲与文件的内存映射结合在一起。进程能够通过系统调用mmap()将一个文件映射到它的用户空间。建立了这种映射以后。就能够像訪问内存一样訪问这个文件。假设将文件的内容以页面为单位缓冲,放在附属于该文件的inode结构的缓冲队列中,那么仅仅要对应的设置进程的内存映射表。就能够非常自然地将这些缓冲页面映射到用户空间中。这样。在按常规方式文件操作訪问一个文件时,就能够通过read()和write()系统调用訪问目标文件的inode结构訪问这些缓冲页面;而通过内存映射机制訪问这个文件时。就能够经由页面映射直接訪问这些缓冲着的页面。当目标页面不在内存中时,常规的文件操作通过系统调用read()、write()的底层将其从设备读入。而通过内存映射机制訪问这个文件时,则由缺页异常的服务程序将目标页面从设备上读入。明确了这个背景,就明确上述的指针为什么叫i_mapping,它指向的数据结构为什么叫address_space就不会奇怪了。

但是,虽然以页面为单位的缓冲对于文件层确实是非常好的选择,对于设备层则不那么合适了。对设备层而言。最自然的当然是以记录块为单位的缓冲,由于设备的读写都是以记录块为单位的。

只是,从磁盘上读写基本的时间都花在准备工作上,一旦准备好了以后读一个记录块与接连读几个记录块相差并不大,并且每次仅仅读写一个记录块反而是不经济的。所以每次读写若干连续的记录块、以页面为单位缓冲并非问题。

还有一方面,假设以页面为单位缓冲。而一个页面相当于若干连续记录块,那么不管是对于缓冲页面还是对于记录块缓冲区,其控制信息显然应该游离于该页面之外,这些信息不应该映射到进程的用户空间。

这个问题不难解决。

在设备层中要保持一些buffer_head结构。让它们的b_data指针分别指向缓冲区页面中的对应位置就能够了。

以一个缓冲页面为例,在文件层它通过一个page数据结构挂入所属inode结构的缓冲页面队列。并且同一时候又能够通过各个进程的页面映射表映射到这些进程的内存空间。而在设备层又通过若干buffer_head结构挂入其所在设备的缓冲区队列。

文件读写的理论

文件读写的理论

在这样一个结构框架中,一旦所欲訪问的内容已经在缓冲页面队列中,读文件的效率就非常高了。仅仅要找到文件的inode结构就找到了缓冲页面的队列,从队列中找到对应的页面就能够读出了。


上面的设备缓冲区队列我们还没介绍是什么东西,以下来介绍

当一个块调入内存时,它要存储在一个缓冲区中。每一个缓冲区与一个块相应。它相当于是磁盘块在内存中的表示,磁盘块包括一个或者多个扇区,可是不能超过一个页面。所以一个物理页能够容纳一个或者多个内存中的块。因为内核在处理数据时须要知道一些相关信息(比方块属于哪一个块设备。块相应于哪个缓冲区等),所以每一个缓冲区都有一个相应的描写叙述符。该描写叙述符用buffer_head结构体表示。成为缓冲区头,在文件<linux/buffer_head.h>中定义,它包括了内核操作缓冲区的所有信息。

文件读写的理论

事实上这个buffer_head存在于linux2.4版本号中。在linux中使用bio结构体取代。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116504.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机网络协议汇总_帧中继是一种什么协议

    计算机网络协议汇总_帧中继是一种什么协议阅读目录1.网络层次划分2.OSI七层网络模型3.IP地址4.子网掩码及网络划分5.ARP/RARP协议6.路由选择协议7.TCP/IP协议8.UDP协议 9.DNS协议10.NAT协议11.DHCP协议12.HTTP协议13.一个举例  计算机网络学习的核心内容就是网络协议的学习。网络…

    2022年9月1日
    7
  • hashmap和hashtable数组扩容_散列表扩容

    hashmap和hashtable数组扩容_散列表扩容前言众所周知,hashmap和Arraylist作为java中非常重要的一种数据结构,应用场景非常广泛,这篇文章主要针对HashMap和ArrayList的扩容机制进行分析。HashMap扩容机制分析在说HashMap扩容机制之前,有必要简述下HashMap的基本结构。以便各位更加清除的理解HashMap的底层是如何扩容的。HashMap自JDK1.8之后结构采用数组+单链表【单链表长度达到…

    2022年9月2日
    11
  • postgresql error /tmp/.s.PGSQL.5432「建议收藏」

    postgresql error /tmp/.s.PGSQL.5432「建议收藏」psql:error:couldnotconnecttoserver:couldnotconnecttoserver:NosuchfileordirectoryIstheserverrunninglocallyandacceptingconnectionsonUnixdomainsocket”/tmp/.s.PGSQL.5432″?通过升级postgresql的方法解决了这个问题:brewpostgresql-upgrad…

    2022年6月19日
    26
  • linux系列之常用运维命令整理笔录

    本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新free-m其中:m表示兆,也可以用g,注意都要小写Men:表示物理内存统计total:表示物理内存总数(total=used+free)use…

    2022年4月7日
    40
  • FFmpeg从入门到精通笔记之四[通俗易懂]

    FFmpeg从入门到精通笔记之四[通俗易懂]介绍在FFmpeg环境下使用libx264进行H.264(AVC)软编码的操作,H.265(HEVC)的编码操作使用的是libx265,但是参数基本类似。FFmpeg软编码H.264与H.265当前网络中常见的视频编码格式要数H.264最为火热,支持H.264的封装格式有很多,如FLV、MP4、HLS(M3U8)、MKV、TS等格式FFmpeg本身并不支持H.264的编码器,而是由第三方模块…

    2022年6月26日
    57
  • 计算机网络协议(三)——UDP、TCP、Socket[通俗易懂]

    计算机网络协议(三)——UDP、TCP、Socket[通俗易懂]底层网络知识详解:最重要的传输层概述一、UDP协议二、TCP协议2.1TCP的三次握手概述这个专栏的计算机网络协议,我是在极客时间上学习已经有三万多人购买的刘超老师的趣谈网络协议专栏,讲的特别好,像看小说一样学习到了平时很枯燥的知识点,计算机网络的书籍太枯燥,感兴趣的同学可以去付费购买,绝对物超所值,本文就是对自己学习专栏的总结,评论区可以留下你的问题,咱们一起讨论!传输层中有两…

    2022年6月7日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号