两个文件描述符指向同一文件

19

使用posix read()和write()的linux调用,如果我通过一个文件描述符写入并通过另一个文件描述符串行读取,这两个动作是互相排斥的,那么我的读取文件描述符是否保证总是能够看到由写入文件描述符最后写入的内容?

我相信这是正确的,但我想确认一下,man页面对此并没有提供很有帮助的信息。

3个回答

30

它取决于您获取两个文件描述符的方式。如果它们来自dup(2)调用,则它们共享文件偏移和状态,因此在其中一个上进行write(2)将影响另一个的位置。另一方面,如果它们来自两个单独的open(2)调用,则每个都将具有自己的文件偏移和状态。

文件描述符主要只是内核文件结构的引用,而正是该内核结构包含了大部分状态。当您打开(2)一个文件时,会得到一个新的内核文件结构和一个新的文件描述符来引用它。当您dup(2)文件描述符(或通过sendmsg传递文件描述符)时,您将获得对同一内核文件结构的新引用。


如果我在每个文件描述符上分别使用open()调用,那么写入fd的数据是否对读取fd可用? - Michael Xu
2
通过两个独立的打开调用,每个fd将有自己的位置。所以如果两者都在文件的开头,并且您使用其中一个写入,另一个仍然会在文件的开头,因此在那里进行的写入将覆盖第一个写入所写的内容,除非您使用O_APPEND打开了文件(在这种情况下,每次写入都会在写入之前隐式地寻找结尾)。 - Chris Dodd
4
谢谢Chris。我的问题有点不同,但是...如果第二个人在读取时,它将完全读取第一个人写的内容。 我的问题的答案是肯定的,保证在写操作返回后从文件读取的任何人都将读取到写操作所写的内容。这是因为Linux锁定了内存中的IO缓存页的访问。 - Michael Xu
我们可以有两个文件描述符指向同一个文件但具有不同的值吗? - Vaggelis Spi
@MichaelXu,你有没有任何参考资料表明,“如果两个文件描述符都指向同一个文件(这两个文件描述符是由分别独立的open(2)创建的),那么从fd上读取将总是得到另一个fd写入的内容”?我不认为Chris Dodd说过这样的话。 - ideawu

1

如果它们都引用同一文件描述符,也就是说你从 "dup" 或 "dup2" 中获取它们(或通过 fork() 继承),那么这是有保证的。

在这些系统调用成功返回后,旧的和新的文件描述符可以互换使用。它们引用同一个打开的文件描述符(参见 open(2)),因此共享文件偏移量和文件状态标志;例如,如果使用其中一个描述符上的 lseek(2) 修改了文件偏移量,则另一个描述符的偏移量也会被更改。


0

当你使用dup()dup2()fork()时, 文件表被两个文件描述符共享。 因此,如果你从一个文件描述符中write一些东西,然后再通过另一个文件描述符write一些东西,那么它会被追加而不是覆盖。

但是,如果两个独立的进程打开同一个文件,则两个进程写入的数据可能会混合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接