Search code examples
clinuxunixforksystem-calls

Process Creation Using Fork()


On running the following code:

#include <stdio.h>
#include <unistd.h>
static int x = 0;
int main(int argc, char *argv[])
{
    pid_t p = getpid();
    fork();
    x++;

    if (! fork()) {
      x++;
      if (fork()) {
          x++;
      }
    }

    printf("p%d: x = %d\n", getpid() - p, x);
    sleep(60);
     return 0;
}

I get the following output:

p0: x = 1
p1: x = 1
p2: x = 3
p3: x = 3
p4: x = 2
p5: x = 2

I don't quite understand how and where the values are incremented. The original process (p0) executes the main() function. The first fork() creates a child process (p1). Both, p0 and p1 then set their copy of x to 1.

Next, both processes create another child process (p2 and p3) on the second fork. The two new child processes p2 and p3 increment their copy of x, i.e., their copy of x becomes 2. But what about p0 and p1? Do they not increment the values?

What's next? How are the values incremented for p4 and p5? Could someone please explain step wise?


Solution

  • fork returns one of the following:

    • -1 on error (and sets errno).
    • 0 in the child.
    • The child's pid (a true value) in the parent.

    Assuming fork doesn't fail, this means !fork() is only true in the child, and fork() is only true in the parent.

                                           p0 p1 p2 p3 p4 p5
                                           -- -- -- -- -- --
    static int x = 0;                   x = 0
    
    // p1 created as a copy of p0.
    fork();                                 0  0
    
    x++;                                    1  1
    
    // p2 created as a copy of p0.
    // p3 created as a copy of p1.
    if (! fork()) {                         1  1  1  1
      // Only p2 and p3 reach here.
      x++;                                  1  1  2  2
    
      // p4 created as a copy of p2.
      // p5 created as a copy of p3
      if (fork()) {                         1  1  2  2  2  2
          // Only p2 and p3 reach here.
          x++;                              1  1  3  3  2  2
      }
    }