TimelordViktorious TimelordViktorious - 17 days ago 6
C Question

Creating multiple processes via "fork" for one parent process

I would like to create a small program that will accept user input from stdin for the number of processes they would like, and then, my program will fork the n number of processes as specified by the user. Later on, I would like to pipe data from the child to the parent.

However, I want only one parent process. I have been trying to figure out the algorithm for this, and perhaps I am overcomplicating it, but I am stuck.

Do note I can only use the fork and pipe features in C (so nothing too crazy!)

Here is my algorithm.

Loop only if I am a parent process, and do not loop if I am a child process.

If I am a parent process entering the loop, then I will call fork(). Otherwise, I am a child, and I will do some child-related tasks (which I may then pipe back to the parent later on). The child should not re-enter the loop as to avoid creating children-of-children processes.

Does that make any sense?

What would you advise me to do?

Answer

Let's say n is the number of children you get as input. Let's see what you could do, if you use one pipe for each child.

In the parent process:

pid_t pid;
int fd[n][2];
for(i = 0; i < n; i++) {
    pipe(fd[i]);
    pid = fork();
    if (pid < 0) {
        perror("whatever");
        exit(1);
    }
    else if (pid == 0) {
        for(j = 0; j < i; j++) {
            if (close(fd[j][0]) < 0) {
                perror("closing fd[0]");
                exit(1);
            }
            if (close(fd[j][1]) < 0) {
                perror("closing fd[1]");
                exit(1);
            }
        }
        func(fd[i]);
    }
}
// other parent stuff next && close file discriptors not needed

And your func() should be what the children have to do. It takes as arguments the 2 file descriptors of the child's pipe. Note that in the end of func you should exit().

A solution making a pipe for each child would be a little better but a little more complex than that (hint: you may pass fd's as arguments, also close all fd's with caution!)

Also, you may keep each child's pid by defining pid_t pid[n]; instead of pid, and refer to each pid as pid[i].

Don't forget to wait for every child to die!