Understanding the processes created by fork()

I have the following code:

#include <unistd.h>
#include <stdio.h> 

main()
{
    int i;

    for(i=0;i<3;i++)
        if(i%2==0) 
            fork();
        else{
            fork();
            fork();
        }
} 

I understand that it has 16 processes in the end (or at least I think it does), but what I don't understand is which processes are the parent processes and which are the child processes. So let's just say that P1 is process 1, P2 is process 2, etc. Is P1 the parent of P2, P3, P5, and P9 (I drew this out in a tree but I'm not sure how accurate my tree is), while P2 is the parent of P4, etc.? Or does P1 become the parent of P2, P3, P4, and something else happens that I don't realize? I'm just kind of stuck.

Answers


I second Jonathon Reinhart's sugestion but instead of ps you might be better served by pstree -p. A quick try shows:

─try(A)─┬─try(B1)─┬─try(C2)─┬─try(D1)───try(13874)
        │         │         └─try(13871)
        │         ├─try(C3)───try(13868)
        │         └─try(13867)
        ├─try(B2)─┬─try(C1)───try(13875)
        │         └─try(13872)
        ├─try(B3)───try(13873)
        └─try(13866)

Back to your question, this is a classic bookkeeping exercise. The one trick is just that: computers are better at bookkeeping.

To simplify things I will present them as if all the processes take a deep breath when a loop iteration is done: this doesn't happen in practice.

  • At the beginning there is one process, the ancestor of them all called A
  • The for starts and since i == 0 you fork and now you have another process, B1 - the son of A
  • The for ends and both processes continue, and in both i == 1.

In this iteration everybody takes the else.

  • A reaches the first fork and suddenly you have B2 - son of A, sibling of B1
  • B2 forks and you have C1 - son of B2
  • A reaches the second fork and you have B3, son of A, sibling of B1 and B2
  • B1 has also reached the first of the two forks so you get C2 - son of B1
  • B1 forks again and you get C3
  • C2 has a chance to run so you get D1

And the fun continues with the next iteration, where all of them will have i==2.


At the end of your main() function, add a call to getchar(). This will keep all processes running indefinitely. Then run $ps -ef to see the full process list. This will show each process's PID and it's parent process's PID. You will then easily be able to derive the hierarchy.


At the end, no processes will be left because all of them do nothing but exit after forking. But while they are running, each of the processes is the direct parent of the one it forked. However, since it's undefined which process gets how much CPU time after forking, after the first fork (P1 spawns P2), it's random if P1 gets CPU time first, so P1 spawns P3, or if the child P2 runs first and spawns P3.

If you put a sleep(1000) at the end of your program and let it run a few times, and use pstree to check them, you'll see that you'll get a different pattern every time.


Need Your Help

Java - Distinct List of Objects

java list collections

I have a list/collection of objects that may or may not have the same property values. What's the easiest way to get a distinct list of the objects with equal properties? Is one collection type best