文件描述符/文件表项

从Linux的层次角度来说,在用户空间是存在这样的概念的,这个概念是存在内核空间的,而且是针对打开的文件的!

进程表

也称进程控制块PCB,由结构task_struct所定义的数据结构。task_struct结构体专门用于存放进程在运行过程中,所涉及到的所有与进程相关的信息。这个结构体的成员项非常多,多达近300个。其中,文件描述符表就被包含在了task_struct结构体当中。在进程运行结束后,进程表所占用的内存空间,会被释放。

三种数据结构

从Linux的层次角度来说,这个概念是存在内核空间的,而且是针对打开的文件的!
内核用三种数据结构来描述一个打开的文件。

打开一个文件的内核数据结构图

关系图

文件描述符表:

open打开文件后,会在进程的task_struct结构体中,创建相应的结构体,用以存放打开文件的相关信息。对文件进行读写等操作时,会用到这些信息,这个数据结构就是我们要讲的文件描述符表
每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的。每个打开的文件描述符表项指向文件表中的一个表项。

文件表

所有”打开的文件”的集合!
每个磁盘文件在打开时都会在内核中建立一个文件表项,内核为所有打开文件维持一张文件表。
每个文件表项包括:

  • 文件状态标志:读、写、添写、同步、非阻塞等
  • 当前文件偏移量
  • 指向该文件v节点表项的指针

文件状态标志

文件状态标志就是open文件时指定的O_RDONLYO_WRONLYO_RDWR等操作权限。open打开文件成功后,就会将文件状态标志保存到文件表中。在对文件执行操作时,会先检查文件状态标志,看看有没有操作权限,然后再去操作文件。

文件偏移量

文件当前读写位置与文件开始位置的距离(字节数)。

函数指针

readwrite等操作文件时,会根据底层具体情况的不同,调用不同的函数来实现读写。在V节点里面保存了这些不同函数的函数指针,方便调用。

v-node

v-node 在(v-node table) 。同文件表一样,所有的进程共享这张v-node表
每个打开文件(或设备)都有个v节点结构。
v节点包含:

  • 文件类型
  • 对此文件进行各种操作的函数指针。

对于大多数文件,v节点还包含了该文件的i节点(索引节点)。

i节点包含:

  • 文件的所有者
  • 文件长度
  • 文件所在设备
  • 指向文件实际在磁盘上所在位置的指针。

文件长度

记录了文件当前的长度,文件长度是动态更新的。

  1. 在文件表或者v索引节点中都有索引计数 (即当前指向该表项的描述符表项数),引用计数为0的时候就可以收回此表项
  2. fork后父子进程各自的每一个打开的文件描述符共享同一个文件表项

参考地址:
什么是"文件表项"
进程表和文件描述表
文件描述符标志/文件表项

您的支持将鼓励我继续创作!