【问题标题】:C pipe stdout to forkC管道stdout到fork
【发布时间】:2018-12-05 12:04:59
【问题描述】:

我正在尝试编写一个使用 pipe 和 fork 执行 ls | wc 的 C 程序,但我无法弄清楚我的代码有什么问题。当我运行下面的代码时,没有返回任何内容。

int main() {
    pid_t p1, p2;
    int fd1[2];

    pipe(fd1);

    p1 = fork();
    if (p1 == 0) {
        close(STDOUT_FILENO);
        dup2(fd1[1], STDOUT_FILENO);
        close(fd1[0]);
        execlp("ls", "ls", (char *)NULL);
    } else {
        p2 = fork();

        if (p2 == 0) {
            dup2(fd1[0], STDIN_FILENO);
            close(fd1[0]);
            close(fd1[1]);

            execlp("wc", "wc", (char *)NULL);
        } else {
            waitpid(p2, 0, WUNTRACED);
            waitpid(p1, 0, WUNTRACED);
        }
    }

    return 0;
}

【问题讨论】:

  • “什么都不返回”是什么意思?
  • 旁注:两个分叉后不对称有什么原因吗?一旦你关闭了你想要dup 的文件描述符,其他时候就不会。您是否有理由不关闭父进程中的管道文件描述符?将0 作为第二个参数int *status 传递给waitpid 的原因是什么?

标签: c linux shell pipe fork


【解决方案1】:

您没有清楚地解释您认为错误的程序在做什么。然而,当我自己运行这个程序时(在添加了适当的标题之后——以后,请不要把这些排除在你的问题之外),它会挂起,直到我按下 control-C。我将假设这是您不想要的,而您确实想要它打印wc 的输出然后退出。

程序挂起,因为在调用wait 时,fd1[1] 在父进程中仍处于打开状态。 wc 将不会收到 EOF 指示,直到 所有 引用管道写入端的文件描述符都关闭。但是父进程在它的两个子进程退出之前不会关闭管道的写入端,并且wc 在它获得 EOF 之前不会退出,所以你有一个死锁。

您需要在第一个if 的父端添加close(fd1[1]),紧接在p2 = fork() 之前。这足以消除僵局。您应该还在waitpid调用之前的第二if的父端添加close(fd1[0])。您还应该检查所有操作是否有错误。

【讨论】:

    猜你喜欢
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多