How can the child process read stdout from the pipe and the parent process write stdin to the pipe?

StackOverflow https://stackoverflow.com/questions/22434732

  •  15-06-2023
  •  | 
  •  

質問

// 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). 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.

More specifically, look at what fork() returns: a PID to the parent, and 0 to the new child. 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. In your case, that's reading in one process and writing in the other.

他のヒント

The system call fork() returns twice. Both in the parent process and the child process. The moment you call fork(), two exact copies of your program are running. The SINGLE difference is the return value of 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:

On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.

So the line that contains 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. Hence the distinction between parent and child.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top