Dean
Dean

Reputation: 37

Why does this code stop running when it hits the pipe?

When this program runs it goes through the loop in the parent then switches to the child when it writes to the pipe. In the child the pipe that reads just causes the program to stop.

Current example output:

Parent 4741 14087 (only this line when 5 more lines are expected)

Expected output(with randomly generated numbers):

Parent 4741 14087

Child 4740 47082

Parent 4741 11345

Child 4740 99017

Parent 4741 96744

Child 4740 98653 (when given the variable 3 and the last number is a randomly generated number)

#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <ctime>
using namespace std;

int main (int argc, char *argv[]) {
    int pid = fork(), temp, randNum, count, pipeName[2], pipeName2[2];
    string conver;
    pipe(pipeName);
    conver = argv[1];
    temp = atoi(conver.c_str());
    char letter;


    if (pid == 0) { //child
        srand((unsigned)time(NULL) * getpid() );
        //closing unused pipes
        close(pipeName2[1]);
        close(pipeName[0]);
        //loop to switch between processes
        for(int i=0; i<temp; i++) {
            count = read(pipeName2[0], &letter, 20);
            randNum = rand();
            cout << "Child " << getpid() << " " << randNum << endl;
            write(pipeName[1], "x", 1);
        }
        close(pipeName2[0]);
        close(pipeName[1]);
    }
    else { //parent
        srand((unsigned)time(NULL) * getpid() );
        pipe(pipeName2);
        //closing unused pipes
        close(pipeName2[0]);
        close(pipeName[1]);
        //loop to switch between processes
        for(int i=0; i<temp; i++) {
            if(i != 0)
                count = read(pipeName[0], &letter, 20);
            randNum = rand();
            cout << "Parent " << getpid() << " " << randNum << endl;
            write(pipeName2[1], "x", 1);
        }
        close(pipeName[0]);
        close(pipeName2[1]);
    }
}

The program ends when it hits the read from pipe line in the child.

Upvotes: 0

Views: 121

Answers (1)

pilcrow
pilcrow

Reputation: 58524

Your principal mistake is fork()ing before you initialize the pipes. Both parent and child thus have their own private (not shared via fd inheritance) pipe pair named pipeName, and only the parent initializes pipeName2 with pipe fds.

For the parent, there's simply no data to read behind pipeName[0]. For the child ... who knows what fd it is writing to in pipeName2[1]? If you're lucky that fails with EBADF.

So, first pipe() twice, and then fork(), and see if that improves things.

Upvotes: 1

Related Questions