User Tools

Site Tools

Fork and processes generation (System Calls: ''fork'')

Concepts:
Use of the system callfork to generate a number of processes.

Text:
Realize a program that receives from command line two integer numbers, n_levels and n_children.
The program (father process) must create a number of children equal to n_children and terminate.
In turn, every child must generate n_children children and terminate.

This process must be repeated n_levels times (at the end (n_children)^(n_levels) leaves processes are in execution).

Such processes (the “leaves” processes) must wait 1 second, and then print (into the screen) a termination message.

/*
Realize a program that receives from command line two integer numbers, n_levels and n_children.
The program (father process) must create a number of children equal to n_children and terminate.
In turn, every child must generate n_children children and terminate.
This process must be repeated n_levels times (in that moment (n_children)^(n_levels) leaves
processes are in execution.
Such processes (the "leaves" processes) must wait 1 second, and then print (into the screen) a
termination message.
*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc,char*argv[]){
pid_t pid;int i, j;int n_levels =atoi(argv[1]);int n_children =atoi(argv[2]);fprintf(stdout,"FIRST PROCESS: PID %d PPID: %d\n", getpid(), getppid());for(i=0; i<n_levels; i++){for(j=0; j<n_children; j++){
pid = fork();if(pid ==0){/* Child */fprintf(stdout,"PID %d PPID %d\n", getpid(), getppid());break;/* The child exits from the inner loop */}}if(pid!=0){/* Father */
sleep(2);/* In order to leave active the father processes when "leaves"
processes terminate their execution. It is useful in order to not have
zombies processes when the last fprintf of this program is executed.
In this case the getppid() function prints the pid of the real father
and not the one of the process init/upstart */exit(0);/* After the generation of n_children children the father ends */}}
sleep(1);fprintf(stdout,"LEAVES: PID %d PPID %d\n", getpid(), getppid());return(0);}

Output:
The output of the program with n_levels=2 and n_children=3 is:

Note that the actual values of the pids change for every execution of the program.

Comments
The most complex part of this program is the code inside the more external for cycle (executed n_levels times):

for(j=0; j<n_children; j++){
pid = fork();if(pid ==0){/* Child */break;}}if(pid!=0){/* Father */exit(0);/* After the generation of n_children children the father ends */}

This code generates n_children child processes and then it ends the execution of the father process.
The father executes n_children forks generating n_children children processes, then it exits the cycle, since the variable pid, in the case of the father, contains a value different from 0 (the system call fork returns to the father the pid of the generated child). To terminate its execution, the father call the system call exit.
Each child executes the instruction break to exit from the for cycle. Otherwise, each child would generating other processes by executing other times the system call fork.

Remember that the break instruction can be substituted with a variable (flag) that involves the exit from the for cycle for the child generated by the system call fork: