补充知识(1)

补充知识(1)
我们认识了文件系统学习操作系统如何管理未打开的文件。操作系统中除了未打开的文件外还存在许多打开的文件。打开一个文件实际上就是将文件从磁盘加载到内存中。此外当内存中的数据长时间未被访问时操作系统也会将该数据踢出内存。本章涉及的第一个话题便是磁盘和内存间的数据交互。磁盘和内存间的数据交互我们可以将内存看做一块对数据临时存取的空间它的传输速度比硬盘快得多。为了更好地利用CPU计算机会利用内存和CPU进行数据交换。但内存能存放的数据是有限的很多时候操作系统需要将数据从磁盘加载到内存中然后再将数据传递给CPU。同时操作系统也需要将内存中无用的数据放回磁盘。问题来了操作系统怎么将数据从磁盘加载到内存中呢以打开文件为例假设此刻操作系统要打开一个文件这个文件的大小是1KB或者是4KB1MB难道在打开文件时操作系统会直接使用内存的1KB4KB或者是1MB空间然后直接将文件放进内存中吗操作系统是不会这么干的。在磁盘与内存交换数据时逻辑上一般以4KB为单位物理内存被分为多部分。这4KB也是交换数据时基本的交互单位。我们一般将内存上这一个4KB的空间叫做页框。为了能够更好地和内存进行交换数据在逻辑上磁盘(卷)也以4KB为单位分为多部分这时的4KB的空间就被称作页帧。因此磁盘与内存之间交换数据就是一个或者多个页框和页帧之间的数据转移。当我们只打开小文件(几个或几百个字节)时这种4KB的数据交换显得有些死板但以4KB为单位进行的数据交换比随意大小的数据交换(需要多少字节就交换多少字节)更有效一点。首先固定单位的内存空间要更容易管理此外当大小固定时读取和写入的效率会变高。我们可以想象一下我们要往内存中的一片区域写1KB数据如果4KB为单位操作系统只需找到一块空闲的空间然后写入数据即可。如果单位不固定代表内存中存放的数据大小也是不固定的空闲空间的大小也不固定我们在找到空闲空间后还需要判断该空间是否足够大。这时候光找到合适的空间就比较花费时间了最后这种直接以4KB为单位的交换是一种基于程序局部性原理的预加载机制这样可能会减少缺页中断的次数。如何管理内存一个4GB的内存操作系统该如何管理内存呢前面说过在逻辑上物理内存被分为多个页框。所以操作系统只要管理这些页框便能管理好内存。那么该怎么管理呢——先描述再组织。Linux中有一个数据结构名为struct page这个结构体中所存的便是一个页框必要的属性信息例如引用计数空闲标志等等。一个内存有多个页框也就有多个page页框因为内存是连续的所以我们可以使用数组管理这多个page所以一个内存就被抽象成一个数组。数组天然具有下标因此每个页框自然具有自己的编号。访问内存时只要从内存地址上找到对应的页框编号然后去page数组中找对应的元素即可。申请内存则是在数组中寻找空闲的page然后分配即可。page数组是内存管理的核心结构当我们访问和申请内存时并不会直接去访问该数组操作系统中有对应的算法不会让我们直接接触数组的。打开文件我们已经知道当我们打开文件时系统会通过文件路径和文件名找到文件对应的inode和内容。现在一个进程已经打开了文件它如何根据这个被打开的文件找到文件属性和文件内容呢在描述打开文件的结构体中有类似的属性名为struct inode通过这一属性便能找到打开文件对应的inode得到该文件的属性。此外在struct file中还存在着描述文件页缓冲区的这一数据结构Linux是通过字典树描述文件的页缓冲区的。其中文件内容也以4KB为单位进行划分在这种划分方式下文件的数据块存在对应的编号然后根据文件数据块编号对应的32为二进制进行划分构造出对应的字典树从而找到对应的页。这也就是打开文件的页缓冲区。