【问题标题】:Which end of a pipe is for input and which for output?管道的哪一端用于输入,哪一端用于输出?
【发布时间】:2011-10-23 15:20:33
【问题描述】:

最近我开始怀疑我错误地使用了管道的末端:

来自手册页:

pipe() 创建一个管道.. ..pipefd[0] 指的是读端 管道。 pipefd[1] 指的是管道的写端。

所以在我看来我是这样的:

                .---------------------------.
               /                            /\
              | pipedfd[0]       pipedfd[1]|  |
process1 ---> |                            | -----> process2
              | input                output|  |
               \____________________________\/

但是,我在这里使用的代码却另有说明:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
  int pipedfd[2];
  char buf[30];

  pipe(pipedfd);
  printf("writing to file descriptor #%d\n", pipedfd[1]);
  write(pipedfd[1], "test", 5);
  printf("reading from file descriptor #%d\n", pipedfd[0]);
  read(pipedfd[0], buf, 5);
  printf("read \"%s\"\n", buf);

  return 0;
}

即写入管道的输出(?)并从管道的输入(?)读取?

【问题讨论】:

  • 尝试检查读写返回的错误,一切都会变得清晰。
  • 读取管道的末端 = 您从中读取的位置 = pipefd[0](不是您 写入 到的部分,如您的图表中所示)。听起来很简单。
  • @Jon 当我想到物理管道时,我认为它有一个输入角(取水)和一个输出角(放水)。我不认为水会流(写)到管道的输出端。这在我看来是违反直觉的。不,我不是管道工。
  • @Pithikos:在这种情况下,物理管道隐喻确实弊大于利。 :)
  • 图表中的箭头与应有的相反。画它们指向相反的方向。

标签: c pipe file-descriptor


【解决方案1】:

简而言之,将图表中的数字 01 互换,您就会得到我将在下面描述的内容。

来自 Mac OS X 手册页:

pipe() 函数创建一个管道(允许单向数据流的对象)并分配一对文件描述符。第一个描述符连接到读取 管道末端;第二个连接到写端。

写入 fildes[1] 的数据出现在 fildes[0] 上(即可以从中读取)。这允许将一个程序的输出发送到另一个程序:源的标准输出 put 设置为管道的写端;接收器的标准输入设置为管道的读取端。管道本身会持续存在,直到所有关联的 描述符已关闭。

我将描述它是如何经常使用的,这样可能会清楚。想象一下,您有一个进程并想要生成一个子进程,您希望向其发送命令。

  • 首先,调用pipe 并获取两个文件描述符。
  • 然后调用fork 来创建孩子。
    • 在孩子中,您关闭 writing 文件描述符 (fd[1]) 并保持 reading 处于打开状态。
    • 在父级中,您执行相反的操作:关闭 reading (fd[0]) 文件描述符并保持 writing 处于打开状态。
  • 现在父级可以写入管道的“他”部分 (fd[1]),而子级可以读取另一部分 (fd[0])。

关闭不是必需的,但通常会完成。如果您需要双向通信,则需要第二组文件描述符以及对pipe 的第二次调用,或者使用双向通道,如 Unix 域套接字或命名管道。

【讨论】:

    【解决方案2】:

    Linux man page for pipe 消除歧义如下:

    写入管道写入端的数据由内核缓冲 直到从管道的读取端读取。

    即你readfd[0]writefd[1]

    【讨论】:

    • @JonPurdy:是的,这就是他的代码正在做的事情,他的图表(和理解)被颠倒了
    猜你喜欢
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 2016-09-28
    • 2019-03-03
    • 2017-06-15
    • 1970-01-01
    相关资源
    最近更新 更多