当通过 fork() 创建子进程时,子进程会获得父进程文件描述符表的完整副本。这意味着子进程的文件描述符表中每个条目指向的 系统级文件表项(File Table Entry)与父进程相同。 父子进程共享文件表项中的文件偏移量(Offset)、打开模式(Read/Write Flags)、文件状态标志等信息。例如,如果父进程写入文件后移动了偏移量,子进程会从新的偏移位置继续操作。

  • 修改文件描述符表本身(如关闭 fd):子进程的操作不会影响父进程。例如,子进程关闭 fd=3,父进程的 fd=3 仍然有效。
  • 修改共享的文件表项(如偏移量、状态标志):子进程的操作会直接影响父进程,因为它们共享同一文件表项。

fork()子进程与父进程之间的文件描述符问题
【Linux】进程间通信

文件描述符相当于一个逻辑句柄,而open,close等函数则是将文件或者物理设备与句柄相关联。

三张表:

  • 文件描述符表:用户区的一部分,除非通过使用文件描述符的函数,否则程序无法对其进行访问。对进程中每个打开的文件,文件描述符表都包含一个条目。
  • 系统文件表:为系统中所有的进程共享。对每个活动的open, 它都包含一个条目。每个系统文件表的条目都包含文件偏移量、访问模式(读、写、or 读-写)以及指向它的文件描述符表的条目计数。
  • 内存索引节点表: 对系统中的每个活动的文件(被某个进程打开了),内存中索引节点表都包含一个条目。几个系统文件表条目可能对应于同一个内存索引节点表(不同进程打开同一个文件)。