【问题标题】:explanation of the dup() system calldup() 系统调用的解释
【发布时间】:2015-10-27 22:25:39
【问题描述】:

当涉及到复制文件描述符时,我能得到一个关于 dup() 函数的简单解释吗? 我想使用管道,但我还必须让孩子从管道中读取(这是简单的部分),但将数据写回父级。 我应该使用另一根管道,还是可以使用相同的管道?

【问题讨论】:

  • 通常使用两个管道:一个用于 child->parent,另一个用于 parent->child。如果使用相同的管道,则无法区分子输入和父输入。
  • 啊哈。所以这将是一个简单的方法。所以我也可以在孩子中创建一个管道,或者我应该在它之外声明它们。
  • 您必须在分叉之前创建两者,否则父级将无权访问。或者,您可以使用socketpair() 进行双向通信。

标签: linux pipe dup


【解决方案1】:

dup()(以及 dup2() 和 dup3())创建重复的文件描述符。

操作系统通过一个参数 dup() 选择一个空闲的文件描述符编号并使其成为传递的那个的副本:

int dup_of_fd = dup(int fd);

使用两个参数 dup2() 它是完全相同的,只是你告诉它你想用作副本的文件描述符编号。如果它已经在使用中(如果在这个例子中 10 已经在使用)那么它(这里是 10)被关闭并作为副本重新打开:

int dup_of_fd = dup2(fd, 10);

使用三个参数 dup3()(特定于 Linux),它与 dup2() 相同,只是您可以传递标志/选项。

在所有情况下,新的(重复的)文件描述符与旧的文件描述符的编号不同,但读取或写入两者将完全相同。

注意,当从 2 个重复的文件描述符中读取时,seek 位置是共享的,所以如果你打开一个文件并将 fd 复制为 dup_of_fd,然后从 fd 读取 10 个字节,然后从 dup_of_fd 读取 10 个字节,从 dup_of_fd 读取的字节将是字节 11 到 20,即使它是从该文件描述符编号的第一次读取。

【讨论】:

  • 哇,太好了
【解决方案2】:

来自man page

dup() 系统调用创建文件描述符 oldfd 的副本, 为新描述符使用编号最小的未使用描述符。

您可以将其视为创建别名。如果调用成功,您将有两个 file descriptors 引用同一资源(文件、管道或其他)。

对于通过管道与子进程通信的用例,您不必使用dup。您需要做的就是调用pipefork 并关闭子进程和父进程中未使用的管道端。

【讨论】:

  • 好的。但是我应该在关闭文件描述符之前调用 dup 函数,还是之后也可以这样做?
  • @Justplayit94 之前。关闭描述符后,它不会引用任何内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多