简体   繁体   English

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

[英]How can the child process read stdout from the pipe and the parent process write stdin to the 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);
    }
}

As what I understood, 据我了解,

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

So, how can the child process read from the pipe AND the parent process write to the pipe in this code? 那么,怎样才能在子进程从管道父进程写入管道在此代码阅读?

The result of fork() is that one process becomes two (by asexual reproduction). fork()的结果是一个过程变成了两个(通过无性繁殖)。 So while it is still the case that exactly one branch of the if/else block will be taken in a process, there are two processes, and one path will be taken by each. 因此,尽管在一个进程中将仅采用if / else块的一个分支的情况仍然存在,但是有两个进程,每个进程都将采用一个路径。

More specifically, look at what fork() returns: a PID to the parent, and 0 to the new child. 更具体地说,请看一下fork()返回的内容:父代PID,新子代0。 Apart from that the two processes are almost identical. 除此之外,这两个过程几乎是相同的。 So the if (cpid == 0) check is a common pattern after fork() so that you can proceed with distinct logic in each process. 因此, if (cpid == 0)检查是fork()之后的常见模式,因此您可以在每个进程中进行不同的逻辑处理。 In your case, that's reading in one process and writing in the other. 就您而言,这是在一个过程中阅读而在另一个过程中写作。

The system call fork() returns twice. 系统调用fork()返回两次。 Both in the parent process and the child process. 在父进程和子进程中都可以。 The moment you call fork() , two exact copies of your program are running. 调用fork() ,程序的两个精确副本正在运行。 The SINGLE difference is the return value of fork() . 唯一的区别是fork()的返回值。

So your "if else only one" rule is still valid when you consider each process in isolation. 因此,当您单独考虑每个进程时,“如果只有一个”规则仍然有效。

Check this resource for a description of the fork call return value: 检查此资源以获取有关fork调用返回值的描述:

On success, the PID of the child process is returned in the parent, and 0 is returned in the child. 成功后,将在父级中返回子进程的PID,在子级中返回0。 On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately. 如果失败,则在父级中返回-1,不创建任何子级进程,并适当设置errno。

So the line that contains cpid = fork(); 因此,包含cpid = fork();的行cpid = fork(); is executed by both process after the fork, where the parent receives the new process' PID and the child receives 0 as PID. 在fork之后由两个进程执行,其中父进程接收新进程的PID,子进程接收0作为PID。 Hence the distinction between parent and child. 因此,父母与子女之间的区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM