Skip to content
Advertisement

Can someone please explain how this works?fork(),sleep()

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

int main(void)

{
  pid_t pids[10];
  int i;

for (i = 9; i >= 0; --i) {
    pids[i] = fork();
    if (pids[i] == 0) {
        printf("Child%dn",i);
        sleep(i+1);
        _exit(0);
    }
}

for (i = 9; i >= 0; --i){
    printf("parent%dn",i);
    waitpid(pids[i], NULL, 0);
    }
return 0;
}

What is happening here? How is sleep() getting executed in the for loop? When is it getting called? Here is the output:

parent9
Child3
Child4
Child2
Child5
Child1
Child6
Child0
Child7
Child8
Child9  //there is a pause here
parent8
parent7
parent6
parent5
parent4
parent3
parent2
parent1
parent0

Please explain this output. I am not able to understand how it’s working. Step by step analysis would be great.

Advertisement

Answer

In the first loop, the original (parent) process forks 10 copies of itself. Each of these child processes (detected by the fact that fork() returned zero) prints a message, sleeps, and exits. All of the children are created at essentially the same time (since the parent is doing very little in the loop), so it’s somewhat random when each of them gets scheduled for the first time – thus the scrambled order of their messages.

During the loop, an array of child process IDs is built. There is a copy of the pids[] array in all 11 processes, but only in the parent is it complete – the copy in each child will be missing the lower-numbered child PIDs, and have zero for its own PID. (Not that this really matters, as only the parent process actually uses this array.)

The second loop executes only in the parent process (because all of the children have exited before this point), and waits for each child to exit. It waits for the child that slept 10 seconds first; all the others have long since exited, so all of the messages (except the first) appear in quick succession. There is no possibility of random ordering here, since it’s driven by a loop in a single process. Note that the first parent message actually appeared before any of the children messages – the parent was able to continue into the second loop before any of the child processes were able to start. This again is just the random behavior of the process scheduler – the “parent9” message could have appeared anywhere in the sequence prior to “parent8”.

I see that you’ve tagged this question with “zombie-processes”. Child0 thru Child8 spend one or more seconds in this state, between the time they exited and the time the parent did a waitpid() on them. The parent was already waiting on Child9 before it exited, so that one process spent essentially no time as a zombie.

This example code might be a bit more illuminating if there were two messages in each loop – one before and one after the sleep/waitpid. It would also be instructive to reverse the order of the second loop (or equivalently, to change the first loop to sleep(10-i)).

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement