Epic-jargon
Epic-jargon

Reputation: 53

c multiple fork and pipe

I'm having problems with my code for my course I have to run different functions in different processes then pipe the results back to the parent and display it. I was having problems so I'm currently trying to understand by doing it in a basic program, but I'm still getting errors.

First i couldnt get pid = wait(&status); it kept saying pid was undefined then when I got around that I moved onto piping but the information doesnt seem to reach the parent.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#define PROCS 5

int main(void){
    int pipes[PROCS][2];
    pid_t ret[PROCS];
    int status = 0;
    int i;
    char msg[PROCS][100];

    for(i = 0;i < PROCS; i++){

    //create pipes
        //create pipes
        if (pipe(pipes[i]) != 0) { // Create a new pipe.
            printf("Could not create new pipe %d", i);
            exit(1);
        }

        if ((ret[i] = fork()) == -1) { 
            printf("Could not fork() new process %d\n", i);
            exit(1);
        }else if (ret[i] == 0) {//if child
            close(pipes[i][1]);
            char string[] = "child process"; //%d - process id = %d\n", i, getpid();
            write(pipes[i][0], string, 25);
            exit(0);
        }
    }
    if(getpid() > 0){
        for(i = 0; i < PROCS; i++) {
            wait(&status);
        }
        for(i = 0; i < PROCS; i++) {
            close(pipes[i][1]);
            read(pipes[i][0], &msg[i], 100);
            close(pipes[i][0]);         
        }
        printf("test 1 : %s\n", msg[0]);
        printf("test 2 : %s\n", msg[1]);
        printf("test 3 : %s\n", msg[2]);
        printf("parent process - process id = %d\n", getpid());     
        exit(0);
    }
}

Upvotes: 2

Views: 3708

Answers (1)

Duck
Duck

Reputation: 27552

    }else if (ret[i] == 0) {//if child
        close(pipes[i][1]);  <== (1)
        char string[] = "child process"; //%d - process id = %d\n", i, getpid();
        write(pipes[i][0], string, 25);  <== (2)
        exit(0);

    //.....

    for(i = 0; i < PROCS; i++) {
        close(pipes[i][1]);
        read(pipes[i][0], &msg[i], 100); <-- (3)
        close(pipes[i][0]);         
    }

By convention the [0] pipe element is for reading and the [1] element for writing. You are writing [0] and then reading [0] in the parent. Fix this and you are good to go.

if(getpid() > 0){

The above is pointless. getpid() is always going to be greater than 0 because every process has a pid greater than zero. You want to do this test on the pid returned from fork that you are storing in ret[i]. That's unnecessary in this case too because your children exit so only the parent will reach this code anyway.

Always, always, always check your return codes. If you had you would have seen straight away that your pipe writes were failing and your pipe reads returning 0.

Upvotes: 2

Related Questions