UNIX文件描述符重用

UNIX File Descriptors Reuse

本文关键字:描述 文件 UNIX      更新时间:2023-10-16

虽然我已经相当习惯UNIX并且在UNIX上编程了很长时间,但我不习惯文件操作。

我知道0/1/2文件描述符是标准的in, out和error。我知道,每当一个进程打开一个文件时,它被赋予一个描述符,它的最小值尚未被使用-并且我理解一些关于使用dup/dup2的事情。

我对进程之间的文件描述符感到困惑。是否每个进程都有自己的输入/输出/错误0/1/2描述符,还是所有进程共享这3个描述符?为什么你可以在3个不同的shell中运行3个程序,如果它们是共享的,它们都只得到它们的程序输出?

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

我知道我以不同的方式问过同样的问题,但我只是想说清楚。越详细越好:)我在编程时从来没有遇到过这些问题,但是我正在阅读一本UNIX书籍以了解更多,我突然意识到这让我很困惑,我以前从未详细考虑过它。

每个文件描述符都是进程本地的。然而,一些文件描述符可以引用相同的文件——例如,如果您使用fork()创建子进程,它将共享父进程打开的文件。它将有自己的一组文件描述符,最初与父文件描述符相同,但它们可以随着关闭/关闭等而改变。

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

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

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

例如,shell可能执行如下命令:

foo | bar

在这种情况下,foo的标准输出必须连接到bar的标准输入。要做到这一点,shell很可能会使用pipe()来创建读取器和写入器文件描述符。它fork()s两次。描述符持续存在。fork()将调用foo,将关闭(1);dup (writer_fd);将writer_fd描述符设置为1。然后它将执行exec(),进程foo将输出到我们创建的管道。对于bar,我们关闭(0);dup(读者);然后exec()。瞧,foo将输出到bar

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