2011-08-19 111 views
3

尽管我对UNIX非常熟悉,并且已经对其进行了很长时间的编程,但我不习惯进行文件操作。UNIX文件描述符重用

我知道0/1/2文件描述符是标准输入,输出和错误。我意识到,无论何时一个进程打开一个文件,它都会被赋予一个最小值的描述符,这个描述符尚未被使用 - 而且我理解了关于使用dup/dup2的一些事情。

虽然我对过程之间的文件描述符感到困惑。每个进程是否有自己的0/1/2描述符用于输入/输出/错误,还是3个描述符在所有进程之间共享?你如何在3个不同的shell中运行3个程序,并且如果他们共享,他们都只能得到他们的程序输出?

如果两个程序在启动后打开myfile.txt,它们都会使用文件描述符#3,还是第二个程序会在使用3之后使用#4?

我知道我在那里以几种方式问过同一个问题,但我只是想说清楚。越详细越好:)编程时,我从来没有遇到过这些问题,但是我正在阅读一本UNIX书以了解更多内容,并且我突然意识到这让我困惑不已,之前的细节。

+0

如果您在发布中添加'c'语言标记,您会收到更好的评论。我想我已经多次讨论过这个问题,所以搜索'[c]标准输出描述符'。祝你好运。 – shellter

+0

谢谢,添加标签 - 我会试着看看其他问题:) –

回答

5

每个文件描述符都是进程本地的。但是,某些文件描述符可以引用同一个文件 - 例如,如果使用fork()创建子进程,它将共享由父进程打开的文件。它有自己的一组文件描述符,最初与父文件相同,但可以通过关闭/复制等方式更改。

如果两个程序打开同一个文件,通常它们会获得单独的文件描述符,指向单独的内部结构。但是,使用某些技术(如fork,FD传递等),可以使不同进程中的文件描述符指向相同的内部实体。不过,一般情况并非如此。

回答你的问题,这两个程序将有FD#3为新打开的文件。

3

Unix中的文件描述符(通常)通过fork()和exec()调用持续存在。所以是的,几个进程可以共享文件描述符。

例如,壳可以做如下命令:

foo | bar 

在这种情况下,Foo的标准输出必须连接到酒吧的标准输入。为此,shell最可能使用pipe()来创建读写器文件描述符。它fork()两次。描述符依然存在。将调用foo的fork()将关闭(1); DUP(writer_fd);编写writer_fd描述符1.然后执行exec(),并将进程foo输出到我们创建的管道。对于酒吧,我们关闭(0); DUP(读取器);然后exec()。瞧,foo会输出到吧。

+2

流程永远不会共享描述符。然而,多个文件描述符(在相同的进程或不同的进程中)可以引用相同的“打开文件描述”,其具有诸如当前位置,非阻塞标志等的共享属性。 –

3

不要将文件描述符与它们表示的资源混淆。你可以有十个不同的进程,每个进程打开一个文件描述符'3',每个进程指向一个不同的打开文件。当一个进程使用其文件描述符进行I/O操作时,操作系统知道哪个进程正在执行I/O,并能够消除正在引用哪个文件。