【文件I/O】 总表和分表
在 Linux 系统中,文件操作中涉及的 总表 和 分表 是 文件描述符管理机制中 的两个重要概念。它们分别对应于 系统级别的文件表 和 进程级别的文件表。
总表(系统文件表)
总表 是 系统级别 的文件表,记录系统中所有打开文件的信息。
每个打开的文件在总表中有一个唯一的条目,与文件对应的内核数据结构(如文件 inode 和文件偏移量)相关联。
存储文件相关的全局信息,包括:
- 文件指针(偏移量)。
- 文件状态(读、写、追加等)。
- 文件的 inode 信息(指向文件元数据)。
确保多个进程共享同一个文件时,能够维护文件的状态一致性。
总表是由操作系统维护的一个全局数据结构,每个打开的文件都会在总表中注册一个条目。总表中的条目通过文件的 文件描述符表(分表) 被进程引用。
分表(进程文件表)
分表 是 进程级别 的文件表,每个进程维护一个自己的分表。
分表中的每一项保存了该进程打开文件的文件描述符及其对应的引用。
存储进程对文件的访问信息,包括:
- 文件描述符(整数形式,如 0、1、2)。
- 指向总表中条目的引用。
- 文件在当前进程中的访问权限(只读、只写、读写等)。
每个进程的分表是独立的,但可以通过文件描述符的共享机制(如 fork())共享文件条目。
分表是一个数组,数组的每一项存储一个文件描述符及其对应的总表条目的引用。当进程打开文件时,会在分表中新增一个条目,并分配一个文件描述符。
特点 | 总表(系统文件表) | 分表(进程文件表) |
---|---|---|
级别 | 系统级别,所有进程共享 | 进程级别,每个进程独立维护 |
作用 | 存储文件全局状态信息 | 存储文件描述符及其对应的总表引用 |
内容 | 文件指针、文件状态、文件 inode 信息 | 文件描述符、文件权限及对总表的引用 |
共享机制 | 多个进程可以共享同一个总表条目 | 分表是独立的,但可以通过 fork() 等方式共享 |
操作对象 | 文件(系统中所有打开的文件) | 文件描述符(进程打开的文件) |
修改范围 | 修改影响所有引用该文件的进程 | 修改仅影响当前进程的文件描述符 |
二者的关系
关联机制:
- 当进程打开文件时,操作系统首先在总表中为该文件分配一个条目。
- 然后在当前进程的分表中建立一个条目,指向总表中的该文件条目。
- 分表中的文件描述符用于引用总表中的信息。
文件偏移量共享:
- 总表中的文件偏移量是共享的。
- 如果多个进程通过文件描述符共享同一个总表条目(如通过 fork() 或 dup()),则它们对文件的读写操作会影响共享的文件偏移量。
通过代码说明总表和分表的作用:
示例:系统调用解析
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
// 打开文件
int fd1 = open("example.txt", O_RDWR | O_CREAT, 0666);
if (fd1 < 0) {
perror("Error opening file");
return 1;
}
// 复制文件描述符
int fd2 = dup(fd1);
// 写入文件
write(fd1, "Hello", 5);
// 调整文件偏移量
lseek(fd2, 0, SEEK_SET);
// 从文件重新读取
char buffer[6] = {0};
read(fd2, buffer, 5);
// 打印读取内容
printf("Read content: %s\n", buffer);
// 关闭文件
close(fd1);
close(fd2);
return 0;
}
// 1. 文件描述符 fd1 和 fd2 的分表条目共享同一个总表条目:
// dup(fd1) 创建了一个新的文件描述符 fd2,但它们指向同一个总表条目。
// 修改 fd1 或 fd2 的文件偏移量会影响对方。
// 2. 写入文件后调整偏移量:
// 调用 write(fd1, "Hello", 5) 将文件偏移量移至文件末尾。
// 通过 lseek(fd2, 0, SEEK_SET) 将文件偏移量重置到文件开头。
// 3. 文件偏移量共享:
// fd1 和 fd2 指向同一个总表条目,因此共享文件偏移量。
// 读取文件时偏移量已经被 lseek() 修改,因此从文件开头读取内容。
输出:
Read content: Hello
总表和分表的共享机制
文件描述符共享的场景:
- fork() 子进程继承父进程的文件描述符:
- 父进程和子进程的分表条目均指向同一个总表条目。
- 父子进程共享文件偏移量。
- dup() 创建文件描述符副本:
- 新的文件描述符与原文件描述符共享总表条目。
- 文件偏移量、文件状态均共享。
- 多进程文件共享:
- 如果多个进程分别打开同一个文件,则每个进程有独立的分表条目,但它们可能指向同一个总表条目。
设计总表的意义:1. 维护全局文件状态,确保文件资源被正确管理。2. 支持文件偏移量共享,提高文件操作的效率。
分表的意义:1. 提供进程级别的文件管理,支持文件描述符的灵活操作。2. 允许文件描述符引用同一文件,但可以设置不同的访问权限。
属性 | 总表(系统文件表) | 分表(进程文件表) |
---|---|---|
级别 | 系统全局 | 进程局部 |
作用 | 存储文件全局状态信息 | 存储进程对文件的访问信息 |
共享性 | 多个进程共享 | 每个进程独立,但文件描述符可共享条目 |
内容 | 文件指针、文件状态、inode 信息 | 文件描述符、权限、对总表的引用 |
总表和分表的分工协作,使得 Linux 文件系统能够高效地管理打开的文件,并支持多进程之间的文件共享。
以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。
我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!