虽然我已经习惯使用UNIX并且已经对它进行了很长时间的编程,但我并不习惯于操作文件。
我知道0/1/2文件描述符是标准输入,输出和错误。我知道无论何时进程打开一个文件,它都会被赋予一个尚未使用的最小值的描述符 - 我理解使用dup / dup2的一些事情。
我对进程之间的文件描述符感到困惑。每个进程是否有自己的0/1/2描述符用于输入/输出/错误,还是在所有进程之间共享的3个描述符?为什么你可以在3个不同的shell中运行3个程序,如果它们被共享,它们都只得到它们的程序输出?
如果两个程序在启动后打开myfile.txt,它们是否都使用文件描述符#3,或者第二个程序是否会使用#4,因为它被采取了?
我知道我曾在几个方面提出同样的问题,但我只是想清楚。越详细越好:)编程时我从来没有遇到过这些问题,但我正在阅读一本UNIX书来了解更多,我突然意识到这让我很困惑,我从来没有在之前的细节。
答案 0 :(得分:5)
每个文件描述符都是进程的本地描述符。但是,某些文件描述符可以引用同一个文件 - 例如,如果使用fork()
创建子进程,它将共享父进程打开的文件。它有自己的一组文件描述符,最初与父文件描述符相同,但它们可以通过关闭/复制等来改变。
如果两个程序打开同一个文件,通常它们会获得单独的文件描述符,指向不同的内部结构。但是,使用某些技术(fork
,FD传递等),您可以让不同进程中的文件描述符指向同一个内部实体。但一般情况并非如此。
回答你的问题,两个程序都有FD#3用于新打开的文件。
答案 1 :(得分:3)
Unix中的文件描述符(通常)通过fork()和exec()调用持久化。所以是的,几个进程可以共享文件描述符。
例如,shell可能会执行如下命令:
foo | bar
在这种情况下,foo的stdout必须连接到bar的stdin。为此,shell很可能使用pipe()来创建读取器和写入器文件描述符。它fork()两次。描述符仍然存在。将调用foo的fork()将关闭(1); DUP(writer_fd);制作writer_fd描述符1.然后它将执行exec(),并且进程foo将输出到我们创建的管道。对于酒吧,我们关闭(0); DUP(读取器);然后是exec()。瞧,foo会输出到bar。
答案 2 :(得分:3)
不要将文件描述符与它们所代表的资源混淆。您可以有十个不同的进程,每个进程的文件描述符为“3”,并且每个进程都引用一个不同的打开文件。当进程使用其文件描述符执行I / O时,操作系统知道正在执行I / O的进程,并且能够消除所引用的文件的歧义。