1

This is my code

#include <iostream>
#include <string>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <stdio.h>
using namespace std;

int main() {

    int pipe_A[2];
    int pipe_B[2];

    pipe(pipe_A);
    pipe(pipe_B);

    pid_t pid_A, pid_B, pid_C;

    if (!(pid_A = fork())) {
        dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */

        system("./data");
        exit(0);
    }

    if (!(pid_B = fork())) {
        dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */
        dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */

        system("grep 5");
        exit(0);
    }

    if (!(pid_C = fork())) {
        dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */

        system("grep 2");
        exit(0);
    }

    return 0;
}

In which "./data" is my test sample that does:

for(int i=0;i<100;i++){
cout<<i<<endl;
}

I tried to build a pipe according to this link:

Apparently my program does not work. After I run my program, there will be two processes doing pipe_wait for ever (I saw that from system monitor). It seems that there are some pipes should be closed. How should I fix it?

Community
  • 1
  • 1
Mars
  • 873
  • 1
  • 11
  • 24

1 Answers1

2

Each child gets its own copy of the parent's file descriptors. And dup2 creates yet another copy. The read side of the pipe will not return EOF until all of the copies of the write side get closed.

So after each call to fork + dup2, go ahead and close all four of pipe_A[0], pipe_A[1], pipe_B[0], and pipe_B[1].

Also close them in the parent after you fork all of the children. (This not strictly necessary in your example, since they will be closed automatically when main() returns. But I would do it anyway for cleanliness.)

Nemo
  • 70,042
  • 10
  • 116
  • 153