Derek
Derek

Reputation: 53

Calculating total number of processes in fork() code

I am trying to determine how many processes are generated in the following code:

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

int main() {  

    int i = 1;

    if (fork()) //parent process will return PID of child.
        i++;
    else if (fork()) //child process (becomes parent)
        i--;
    else //grandchild process returns 0
        i++;

    printf("%d\n", i);
}

Generally, the formula for total # of processes is 2^n where n is the number of fork system calls. I am confused because this sample involves if/else conditional statements.

I am getting 4 processes in total. (2 processes from the if (fork()) statement and 2 processes from the else if (fork()) statement). Can someone confirm if this is correct or not? And if not, can you please guide me in the right direction / explain how to calculate the number of processes. This is something I'm having quite a bit of trouble determining.

Upvotes: 2

Views: 5231

Answers (2)

Shakiba Moshiri
Shakiba Moshiri

Reputation: 23794

Instead of your code, try this one:

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

int main()
{
    int counter = 0;

    if( fork() )
    {
        // should be the parent
        fprintf( stderr, "1. process ID: %d\n", getpid() );
        fprintf( stderr, "1. parent process ID: %d\n", getppid() );
        ++counter;
    }
    else
    if( fork() )
    {
        fprintf( stderr, "2. process ID: %d\n", getpid() );
        fprintf( stderr, "2. parent process ID: %d\n", getppid() );
        --counter;
    }
    else
    {
        fprintf( stderr, "3. process ID: %d\n", getpid() );
        fprintf( stderr, "3. parent process ID: %d\n", getppid() );
        ++counter;
    }

    printf( "counter: %d\n", counter );
}

And here is the output of the running code:

ALP ❱ gcc temp.c
ALP ❱ ./a.out 
1. process ID: 6672
1. parent process ID: 3037
counter: 1
2. process ID: 6673
2. parent process ID: 6672
counter: -1
3. process ID: 6674
3. parent process ID: 2008
counter: 1
ALP ❱ ps
  PID TTY          TIME CMD
 3037 pts/2    00:00:01 bash
 5354 pts/2    00:00:00 redshift
 6642 pts/2    00:00:00 ps
ALP ❱ ps -e | grep 2008
 2008 ?        00:00:00 upstart
ALP ❱ 

Now what is going on is this:

3037 is process ID on my machine 2008 is the process ID of upstart (= taking care of zombie-process here)
6672 is the process ID of main function
6673 is the first child process and its parents is main: 6672
6674 is the second child process and 2008 (=upstart) become its parents

Although I am not sure, but I guess you have 2 child processes along the main, therefore 3 in total. Since you did not check for -1 the failure of calling fork(2), it may be different on others running the code.


NOTE
Since you did not wait(2) for your children and main exits without terminating them, upstart(8) takes care of terminating them.

NOTE 2
You should not use fork(2) in this manner.

Upvotes: 1

Neb
Neb

Reputation: 2280

Pay attention: the if () statements will be evaluated true even if the fork() does not succed since in this case it returns a negative number which is different from 0 and so true.

You have 3 processes

The first fork() generate a copy of the parent process, i.e, a child. Now you have 2 processes. The fork() returns the child PID to the parent. This makes the first if() condition true for the parent, and false for the children. The parent increments the variable i.

So, the child flow goes into the second if statement which executes a fork before being evalated. The fork generates a copy of the child (which now became the parent), i.e, a grandchild. You now have 3 processes.

The child evaluates the else if condition true and will decrement the i while the grandchild evaluates false and will increment i.

As a matter of what I say, if you try to exectute your program, you'll get only 3 outputs (3 printf() executed). The order of the output depends on how the processes are scheduled by the CPU scheduler and it's something you cannot predict.

Upvotes: 2

Related Questions