Pithikos
Pithikos

Reputation: 20300

Forking in a loop does not work as thought

I want to have the main process to run and create 4 subprocesses. Once they are created I want the main process to wait for them to finish.

This is my whole code:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>


int main(){

    int i;
    int childID;
    int status;

    for (i=0;i<4;i++){
        childID=fork();
        if (childID==0){
            printf("[%d] I the child, will sleep\n", (int)getpid());
            sleep(1);
        }
    }

    if (!childID){
        wait(&status);
        printf("[%d] I the parent, have waited for my children!\n", (int)getpid());
    }

    return 0;
}

What I get instead is this:

..
[8508] I the child, will sleep
[8503] I the parent, have waited for my children!
[8511] I the child, will sleep
[8510] I the child, will sleep
[8509] I the child, will sleep
[8520] I the child, will sleep
[8511] I the parent, have waited for my children!
[8510] I the parent, have waited for my children!
(prompt stuck)

Why does the parent print out multiple times instead of once, in the end?

Upvotes: 0

Views: 809

Answers (3)

murgatroid99
murgatroid99

Reputation: 20267

When you run the loop, once you fork, the child sleeps during the first iteration after it is forked off, but then it forks off more processes. Since childID is no longer 0 for those processes, the do not call wait and so they do not reap their children. This means that when all of the wait calls are completed you will still have processes running, so the terminal will hang.

Upvotes: 0

Russell Borogove
Russell Borogove

Reputation: 19037

Look at the pids of the prints. 8510 and 8511 are children, not the original parent. When you fork in the loop, the children are also in that loop. Try putting a break; after the sleep(1).

Upvotes: 1

K-ballo
K-ballo

Reputation: 81349

Is not the parent who writes multiple times, but the first 3 children. When you fork, the children gets an exact copy of the process including its address space, stack, registers, everything. That means that after the first fork both the parent and the new child will go through the for 3 more times creating 3 new childs. You should break out of the for when executing as the children for the desired effect:

    if (childID==0){
        printf("[%d] I the child, will sleep\n", (int)getpid());
        sleep(1);
        break;
    }

Upvotes: 3

Related Questions