Koen Savelkoul
Koen Savelkoul

Reputation: 17

Only 1 child after 5 forks (C)

I am trying to make a processor farm in C. I start with opening message queues, and afterwards try to make worker processes: (note that NROF_WORKERS is 5)

static void
makechildren (void) {
    // Only the parent should fork. Any children created will become workers. 
    pid_t   processID; 
    pid_t   farmerPID = getpid(); // To identify who the farmer is

    // Loop creating processes, indexed by NROF_WORKERS
    int i = 0; 
    while (i < NROF_WORKERS){
        if (getpid() == farmerPID){
            i++; 
            printf ("Parent is creating a child!%d\n", getpid()); 
            processID = fork();
        }
    }

    if (processID < 0){
        perror("fork() failed");
        exit(1);
    }
    else {
    // If parent, start farming
        if (processID == farmerPID) {
            printf("Parent reporting in!%d\n");
        }
    // If child, become a worker
        if (processID == 0) {
            printf("Child reporting in!%d\n", getpid()); 
            join();
        }
    }
}

As you can see, I want the parent to report any time a child is created, and afterwards I want the parent and all children to report. However, this is all I get:

Parent is creating a child!11909
Parent is creating a child!11909
Parent is creating a child!11909
Parent is creating a child!11909
Parent is creating a child!11909
Child reporting in!11914

Now, I do notice the difference in 11909 and 11914 is 5. So my question: are the other processes created? If so, how come they don't report? And if not, what am I doing wrong? Also, the parent is not reporting at all, how is this caused?

Upvotes: 1

Views: 75

Answers (2)

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36401

You always print the farmerPid! But as the message is printed 5 times, you effectively created 5 processes:

while (i < NROF_WORKERS){
    if (getpid() == farmerPID){
        i++; 
        printf ("Parent is creating a child!%d\n", getpid()); 
        processID = fork();
    }
}

If you want to print the children pids then your code must makes a difference in between parent and child, as in:

while (i < NROF_WORKERS){
    if (getpid() == farmerPID){
        i++; 
        printf ("Parent is creating a child!\n"); 
        processID = fork();
        if (processID==0) { // child
            printf("I am the child %d\n",getpid());
        } else { // parent
            printf("Parent just created child %d\n",processID);
        }
    }
}

Upvotes: 0

Eugene Sh.
Eugene Sh.

Reputation: 18371

All of the children are created, but will loop forever in the while loop, as i is incremented only for the parent:

int i = 0; 
while (i < NROF_WORKERS){
    if (getpid() == farmerPID){    
        i++;             // <---- This is happening for the parent process only.
        printf ("Parent is creating a child!%d\n", getpid()); 
        processID = fork();
    }
}

The only child to terminate is the last one, for which the i is equal to NROF_WORKERS.

Also parent is "not reporting" since the processID you are checking to be equal to the parent PID is never equal to it, as it is equal to the latest fork result, i.e. the latest created child PID:

.........
 processID = fork();
.........
.........
 if (processID == farmerPID) {
            printf("Parent reporting in!%d\n");
 }

Upvotes: 2

Related Questions