c - POSIX 进程和文件描述符

标签 c linux posix

我是 C 下进程使用的新手,我有与子进程中文件描述符的 linux 行为相关的问题。

查到子进程和父进程共享文件描述符的信息,还有编号为0,1,2的文件描述符是标准输入输出和错误, 所以我认为,如果我 fork 进程,我将拥有相同的输入和输出目录,但是当我在子进程中更改它时,它们在父进程中没有更改。我的问题是,它是否适用于每个文件描述符,所以如果我决定在子进程中覆盖文件描述符编号 100,它在子进程和父进程中会有所不同,或者只有文件描述符 0、1、2 被认为是特殊的。

最好的问候

最佳答案

POSIX 线程实际上与 fork 没有什么特别的关系,所以我假设您是在谈论进程而不是线程。有了线程,就没有父子的概念,两者共享相同的数据。

对于进程,每个进程都有自己的一组文件描述符,它们是唯一的,一个小的非负数(不是文件句柄, 这是 C 的一个概念)。

但是,这些文件描述符都指向共享池中的条目(例如,在内核中)。这允许所有进程拥有自己的标准输入、输出和错误(描述符 0、1 和 2),但它们可能引用相同的“支持文件”。

因此,当您的进程 fork 时,它会获得自己的文件描述符,但它们指向与父进程相同的共享池条目。

如果 child 然后关闭其文件描述符并重新打开它以指向其他地方,那只会影响 child ,不会影响 parent 。

假设您有三个进程作为两个 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 上自动关闭,你必须显式地标记一个描述符。

关于c - POSIX 进程和文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17100425/

相关文章:

c++ - 英特尔® TinyCrypt : how to use AES-128/CTR

c - 没有 udev 或 libusb 的 linux 上的 usb 连接事件

c - 创建一个没有 malloc 的链表

使用分配的内存将整数复制到整数

linux - 我可以告诉 Linux 不要换出特定进程的内存吗?

linux - 通过 sed 查找变量模式匹配并删除行

c++ - 对 LibSerial 的 undefined reference

linux - 在后台运行 shell 脚本

c - 很好的 C 库集合?

linux - 在 curl 获取的 2 个文件之间添加一个新行