Search code examples
processtreeoperating-systemtreeview

What is the process tree of this statement?


I have the following statement:

if(!fork() || (fork() && fork())){ fork(); }

and I need to draw the process tree resulting of this statement.

Can someone please explain to me how can we draw the process tree when we have something like this, I tried seeing on youtube but all the one I found are simple multiple fork() statements after eachother but nothing like this, I would really appreciate the help. I tried and I got:

  P0
   |
   P1
 / |  \
P2 P3  P4

Is this correct?


Solution

  • No, there are six processes involved, not five. Although there are just four distinct fork() expressions in the code, one of them will be executed by two processes.

    To analyse this, it is important to understand the following two points:

    • Shortcut evaluation: both || and && are shortcut evaluation operators, and so some processes will abort further evaluation of the if expression.

    • The child process created by fork() will see a return value of 0, while the original process will get a non-zero value.

    Let's first untangle the boolean expression and write the || as an if ... else statement that is equivalent:

    if ( !fork() ) {
        fork();
    } else if ( fork() && fork() ) {
        fork();
    }
    

    Note that the two inner code blocks stem from the single block in the original code. But by writing it this way, we already see that two different processes will execute that same (original) block.

    Now let's untangle the && operator by writing nested if statements that perform an equivalent evaluation:

    if ( !fork() ) {
        fork();
    } else {
        if ( fork() ) {
            if ( fork() ) {
                fork();
            }
        }
    }
    

    Let's add comments to the above code to indicate which process runs which piece of code. The numbering of the processes is a free choice, so feel free to use different numbers:

    // P0
    if ( !fork() ) { // P0 creates P1
        // Only P1 executes this
        fork(); // P1 creates P2
    } else {
        // Only P0 executes this
        if ( fork() ) { // P0 creates P3
            // Only P0 executes this
            if ( fork() ) { // P0 creates P4
                // Only P0 executes this
                fork(); // P0 creates P5
            }
        }
    }
    

    This means the process tree has the following shape:

          ___P0___
         /  |  |  \
        P1  P3 P4  P5
        |  
        P2