Linux文件描述符和打开文件之间的关系

简介: 文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而,实际并非如此。多个文件描述符指向同一打开文件,这既有可能,也属必要。这些文件描述符可在相同或不同的进程中打开。要理解具体情况如何,需要查看由内核维护的 3 个数据结构。进程级的文件描述符表。系统级的打开文件表。文件系统的 i-node 表。上述讨论揭示出如下要点。两个不同的文件描述符,若指向同一打开文件句柄,将共享同一文件偏移量。

简介

文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而,实际并非如此。多个文件描述符指向同一打开文件,这既有可能,也属必要。这些文件描述符可在相同或不同的进程中打开。

要理解具体情况如何,需要查看由内核维护的 3 个数据结构。

  • 进程级的文件描述符表。
  • 系统级的打开文件表。
  • 文件系统的 i-node 表。

1.进程级的文件描述符表。

针对每个进程,内核为其维护打开文件的描述符表。该表的每一条目都记录了单个文件描述符的相关信息,如下所示。

  • 控制文件描述符操作的一组标志。
  • 对打开文件句柄的引用。

2.系统级的打开文件表。

内核对所有打开的文件维护有一个系统级的描述表格。有时,也称之为打开文件表,并将表中各条目称为打开文件句柄。一个打开文件句柄存储了与一个打开文件相关的全部信息,如下所示。

  • 当前文件偏移量(调用 read()和 write()时更新,或使用 lseek()直接修改)。
  • 打开文件时所使用的状态标志(即,open()的 flags 参数)。
  • 文件访问模式(如调用 open()时所设置的只读模式、只写模式或读写模式)。
  • 与信号驱动 I/O 相关的设置
  • 对该文件 i-node 对象的引用。

3.文件系统的 i-node 表。

每个文件系统都会为驻留其上的所有文件建立一个 i-node 表。第 14 章将详细讨论 i-node 结构和文件系统的总体结构。这里只是列出每个文件的 i-node 信息,具体如下。

  • 文件类型(例如,常规文件、套接字或 FIFO)和访问权限。
  • 一个指针,指向该文件所持有的锁的列表。
  • 文件的各种属性,包括文件大小以及与不同类型操作相关的时间戳。

此处将忽略 i-node 在磁盘和内存中的表示差异。磁盘上的 i-node 记录了文件的固有属性,诸如:文件类型、访问权限和时间戳。访问一个文件时,会在内存中为 i-node 创建一个副本,其中记录了引用该 i-node 的打开文件句柄数量以及该 i-node 所在设备的主、从设备号,还包括一些打开文件时与文件相关的临时属性,例如:文件锁。

图文细嗦

image-20231024210621670

​ 上图展示了文件描述符、打开的文件句柄以及 i-node 之间的关系。在下图中,两个进程拥有诸多打开的文件描述符。

在进程 A 中,文件描述符 1 和 20 都指向同一个打开的文件句柄(标号为 23)。这可能是通过调用 dup()、dup2()或 fcntl()而形成的

​ 进程A的文件描述符2和进程B的文件描述符2都指向同一个打开的文件句柄(标号为73)。这种情形可能在调用 fork()后出现(即,进程 A 与进程 B 之间是父子关系),或者当某进程通过UNIX 域套接字将一个打开的文件描述符传递给另一进程时,也会发生

​ 此外,进程 A 的描述符 0 和进程 B 的描述符 3 分别指向不同的打开文件句柄,但这些句柄均指向 i-node 表中的相同条目(1976),换言之,指向同一文件。发生这种情况是因为每个进程各自对同一文件发起了 open()调用。同一个进程两次打开同一文件,也会发生类似情况。

总结

上述讨论揭示出如下要点。

  • 两个不同的文件描述符,若指向同一打开文件句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量(由调用 read()、write()或 lseek() 所致),那么从另一文件描述符中也会观察到这一变化。无论这两个文件描述符分属于不同进程,还是同属于一个进程,情况都是如此。
  • 要获取和修改打开的文件标志(例如,O_APPEND、O_NONBLOCK 和 O_ASYNC),可执行 fcntl()的 F_GETFL 和 F_SETFL 操作,其对作用域的约束与上一条颇为类似。
  • 相形之下,文件描述符标志(亦即,close-on-exec 标志)为进程和文件描述符所私有。对这一标志的修改将不会影响同一进程或不同进程中的其他文件描述符。
目录
相关文章
|
2天前
|
Linux
Linux文件误删恢复
请注意,成功恢复误删文件的机会取决于多个因素,包括文件被删除后经过的时间、磁盘的使用情况以及您采取的操作。因此,尽可能快速采取行动,并避免在误删文件所在的磁盘上写入新数据,以提高恢复成功的可能性。
5 0
|
3天前
|
存储 监控 Linux
|
3天前
|
安全 Linux
【亮剑】如何在Linux使用 chattr 命令更改文件或目录的扩展属性?
【4月更文挑战第30天】`chattr`是Linux中用于管理文件和目录扩展属性的命令,影响文件系统处理方式。常用属性包括:`a`(追加)、`i`(不可变)、`s`(安全删除)和`S`(同步更新)。通过`chattr [选项] <模式> <文件或目录>`设置属性,如`chattr +i <文件名>`使文件不可变,`-i`移除不可变属性。`lsattr`用于查看属性。注意,只有root用户有权更改属性,不是所有文件系统都支持所有属性,且更改关键文件属性前应备份。`chattr`有助于提升系统安全性和数据保护。
|
3天前
|
Linux 开发者
【亮剑】Linux 中的文件锁定命令:flock、fcntl、lockfile、flockfile
【4月更文挑战第30天】本文介绍了Linux系统中的四种文件锁定机制:flock、fcntl、lockfile和flockfile,用于多进程环境下协调共享资源访问,防止数据损坏和竞争条件。flock适合脚本,fcntl提供底层灵活性,lockfile用于管理锁定文件,flockfile则结合两者功能。选择锁定策略时需考虑应用场景,如脚本可选flock,复杂需求则用fcntl。理解并正确使用这些工具对保证系统稳定性和数据一致性至关重要。
|
4天前
|
存储 算法 Linux
【Linux】文件打包解压_tar_zip
【Linux】文件打包解压_tar_zip
14 0
【Linux】文件打包解压_tar_zip
|
4天前
|
Linux 开发者
【Linux】:文件查看 stat、cat、more、less、head、tail、uniq、wc
【Linux】:文件查看 stat、cat、more、less、head、tail、uniq、wc
13 1
|
4天前
|
安全 Linux 数据处理
|
4天前
|
Linux
|
5天前
|
存储 Unix Linux
Linux文件结构与文件权限
Linux文件结构与文件权限
4 0
|
5天前
|
安全 Linux 数据安全/隐私保护
【专栏】如何在 Linux 中查找文件所有者?
【4月更文挑战第28天】在 Linux 系统中,掌握查找文件所有者的方法对于系统管理和安全审计至关重要。本文介绍了基本和高级技巧:使用`ls -l`和`stat`命令查看文件详细信息,通过文件路径、通配符或结合`find`、`grep`命令进行查找。实际案例包括查找特定、多个及隐藏文件的所有者。注意权限、文件系统类型和系统环境可能影响查找。了解这些方法能提升 Linux 系统管理效率。