说我有流程1和流程2。两者都有一个对应于整数 4 的文件描述符。
然而,在每个进程中,文件描述符 4 都指向内核打开文件表中的一个完全不同的文件:
这怎么可能?文件描述符不应该是打开文件表中记录的索引吗?
答案1
文件描述符(即4
您的示例中的 )是特定于进程的索引文件描述符表,不是打开的文件表。文件描述符条目本身包含内核全局打开文件表中条目的索引以及文件描述符标志。
答案2
每个进程都有自己的文件描述符表。进程1234中的文件描述符4指向进程1234的表内部。进程 5678 中的文件描述符 4 指向进程 5678 的表内部。您必须熟悉的一个情况是文件描述符 0、1 和 2,它们对于每个进程来说是标准输入、标准输出和标准错误,指向它们被重定向到的位置。
一个进程可以多次打开同一个文件。这可能会同时发生,例如,当进程的标准输出和标准错误重定向到同一终端或同一文件时。底层文件表条目(例如Linux的struct file
) 携带的不仅仅是有关文件的信息;它们还包含打开模式(例如读或写)和其他状态(例如标志,例如执行时关闭)。例如,进程可能打开一个终端以仅在文件描述符 0 上读取,并且打开同一终端以仅在文件描述符 2 上写入。文件表条目还包含进程在文件中的位置;一个进程可能想要lseek
访问同一文件中的两个不同位置,因此将用来dup
获取该文件的两个句柄。
答案3
每个进程都有自己的文件描述符表。就这样。
这一切都被很好地描述在UNIX网络编程如果您想深入学习,请阅读理查德·史蒂文斯 (Richard Stevens) 的著作。
答案4
为了直观地了解为什么每个文件描述符都应该在本地文件描述符表上建立索引,可以查看以下情况重定向在unix系统中。对于一个进程,可以将其标准输出重定向到任何其他文件,从而重载该进程的文件描述符“1”,而不改变“1”对其他进程的含义。对于 stdin 和 stderr 也是如此。因此必须有一个本地文件描述符来支持这种行为。