我是一个在C下使用进程的新手,我有一个关于子进程中文件描述符的linux行为的问题。
我已经发现了文件描述符在子进程和父进程之间共享的信息,而且编号为0、1、2的文件描述符是标准输入输出和错误,所以我认为如果我派生进程,我将拥有相同的输入和输出目录,但是当我在子进程中更改它时,它们在父进程中不会更改。我的问题是,它是否适用于每个文件描述符,所以如果我决定重写子进程中的文件描述符号100,那么子进程和父进程中的文件描述符号就会不同,或者只有文件描述符0、1、2被认为是特殊的。
诚挚的问候
发布于 2013-06-14 11:11:04
POSIX线程实际上与fork没有什么特别的关系,所以我假设您谈论的是进程而不是线程。对于线程,没有父和子的概念,它们共享相同的数据。
对于进程,每个进程都有自己唯一的一组文件描述符,一个小的非负数(而不是文件句柄,这是C语言的一个概念)。
但是,这些文件描述符都指向共享池中的条目(例如,在内核中)。这允许所有进程都有自己的标准输入、输出和错误(描述符0、1和2),但它们可能引用相同的“备份文件”。
因此,当您的进程派生时,它会获得自己的文件描述符,但它们指向与父进程相同的共享池条目。
如果子进程随后关闭其文件描述符,并重新打开它以指向其他位置,则只影响子进程,而不影响父进程。
因此,假设您有三个进程作为两个fork的结果,并且进程C已关闭并重新打开其标准输出以转到一个文件。这是关于你所处的情况的(某种)图形指示:
Individual processes Shared pool
+------+ +------------------+
Process A | fd 1 | ----+----> | maps to /dev/tty |
+------+ | +------------------+
Process B | fd 1 | ----+
+------+ +------------------+
Process C | fd 1 | ---------> | maps to new file |
+------+ +------------------+这种行为并不是三个标准描述符所特有的,它适用于所有的描述符。事实上,描述符不仅在fork中存在,而且(通常)在exec中也存在,这使得重定向可以在类UNIX操作系统下工作。如果希望在exec上自动关闭描述符,则必须显式标记描述符。
发布于 2013-06-14 11:11:03
您可以将文件描述符视为数组中的索引。因此,标准输入/输出/错误的描述符并没有什么特别之处。
一旦你派生了这个过程,就会有两个这样的数组,一个用于父对象,另一个用于子对象。它们一开始都是一样的,因为它被复制了,但是一旦不同的进程开始打开和关闭其他文件描述符,它们就会开始分歧。
发布于 2013-06-14 11:18:37
子进程在执行fork()时会获得父进程打开的文件表的副本,但在此之后,父进程或子进程中的任何更改(例如打开新的文件描述符或关闭现有的文件描述符)都不会反映在另一个进程中。在这方面,文件描述符0、1和2没有什么特别之处。
然而,请注意,即使打开的文件表(即,文件描述符集)被复制,则由这些描述符引用的打开文件不被复制。这意味着对打开文件的更新(例如,使用lseek()更改当前文件位置)会影响两个进程。
对于线程来说,这是另一回事。同一进程中的线程共享相同的打开文件表,因此所有线程都可以看到一个线程中的更改。同样,在这方面,文件描述符0、1和2没有什么特别之处。
https://stackoverflow.com/questions/17100425
复制相似问题