子进程如何从管道读取stdout,父进程将stdin写入管道?

时间:2014-03-16 08:37:49

标签: c linux pipe

// This code is pasted from
// http://linux.die.net/man/2/pipe

#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    char buf;
    if (argc != 2) {
    fprintf(stderr, "Usage: %s <string>\n", argv[0]);
    exit(EXIT_FAILURE);
    }
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (cpid == 0) {    /* Child reads from pipe */                   <----- Point A
        close(pipefd[1]);          /* Close unused write end */
        while (read(pipefd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);
        write(STDOUT_FILENO, "\n", 1);
        close(pipefd[0]);
        _exit(EXIT_SUCCESS);
    } else {            /* Parent writes argv[1] to pipe */           <----- Point B
        close(pipefd[0]);          /* Close unused read end */
        write(pipefd[1], argv[1], strlen(argv[1]));
        close(pipefd[1]);          /* Reader will see EOF */
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}

据我了解,

if (...)
  ............;   ---+
else                 |---> " Only ONE of them can be reached! "
  ............;   ---+

那么,子进程如何从管道中读取 AND 父进程在此代码中写入管道?

3 个答案:

答案 0 :(得分:3)

fork()的结果是一个过程变为两个(通过无性繁殖)。因此,虽然if / else块的一个分支仍然在一个进程中被占用,但是有两个进程,每个进程都会占用一个路径。

更具体地说,查看fork()返回的内容:父级的PID,新子级的0。除此之外,这两个过程几乎完全相同。因此if (cpid == 0)检查是fork()之后的常见模式,因此您可以在每个过程中继续使用不同的逻辑。在你的情况下,这是在一个过程中阅读和在另一个过程中写作。

答案 1 :(得分:1)

系统调用fork()返回两次。父进程和子进程都有。您拨打fork()的那一刻,您的程序的两个完全副本正在运行。 SINGLE差异是fork()的返回值。

因此,当您单独考虑每个流程时,您的“if else only one”规则仍然有效。

答案 2 :(得分:1)

检查此资源以获取fork call返回值的说明:

  

成功时,将返回子进程的PID   父项,并在子项中返回0。失败时,返回-1   在父级中,不创建子进程,并设置errno   适当。

因此包含cpid = fork();的行由fork之后的两个进程执行,其中父进程接收新进程'PID,子进程接收0作为PID。因此,父母和孩子之间的区别。