C语言 子进程挂起,即使在关闭其输入后也是如此



>假设我有这个示例代码(为了清楚起见,基本上省略了错误检查(

static void c_way() {
    int pipefd[2], ch;
    FILE *rf, *wf;
    pipe(pipefd);
    switch (fork()) {
    case -1:
        /* something went wrong */
        break;
    case 0:
        dup2(pipefd[0], STDIN_FILENO);
        dup2(pipefd[1], STDOUT_FILENO);
        close(pipefd[0]);
        close(pipefd[1]);
        execvp(cat_args[0], cat_args);
        _exit(0);
    }
    rf = fdopen(pipefd[0], "r");
    wf = fdopen(pipefd[1], "w");
    fprintf(wf, "I have %d apples.n", 5);
    fclose(wf);
    while ((ch = fgetc(rf)) != EOF)
        putchar(ch);
    puts("Done reading.");
    fflush(stdout);
    fclose(rf);
}

cat_args只是{"cat", "-", NULL}.出于某种原因,尽管已经关闭了管道的父进程的写入端,但 EOF 似乎从未在fgetc循环中到达,就好像子进程正在等待更多输入一样。我忘了关闭一些文件描述符吗?即使不使用文件指针(即 POSIX 读取和写入.raw它仍然挂起。

我看到一些类似的回答问题,所以这可能是重复的。

当我运行这段代码时,我看到:

[notroot]$ ./c_way 
I have 5 apples.

然后是挂。

这是一场比赛:你的父进程在子进程exec的cat之前从管道中读取自己刚刚写入的数据(并将其写入stdout(。

孩子什么也没读——管道已经被父母排干了——因此耐心地阻止了等待输入的 stdin。 与此同时,父级耐心地阻止管道的读取端,等待永远不会到达的输入。

您需要两个管道:一个用于将父级连接到子标准输出,另一个用于将子标准输出连接到父级。 (另请参阅套接字对

最新更新