Process
Process
fork() is a system call used to create a new process. The new process is called a child process and
the original process is called the parent process. The child process by default is a duplicate of the
parent process. By duplicate we mean that the child process has the same code as the parent
process but the memory space of both the processes is separate. The syntax of using fork() is :
#include<unistd.h>
pid_t fork(void);
fork() returns -1 on failure; On success it returns „0‟ in the child process and process-id of the
child in the parent process.
It may happen that a process is required to do two tasks that are independent. Since the tasks are
to be done by the same process, they can be executed one after the other only. Now to do the
same task in roughly half the time the process (parent) creates a new process (child). One of the
task is performed by the parent and the other by the child. Consider it as a situation where you
are supposed to do to two tasks and to complete them in quick time you take help of your friend
which does one of the task for you.
We know that a process is program in execution. For the parent process the program is written by
the programmer but from where the child gets its program? The child runs the same code as its
parent, hence, it is called a duplicate process.
If the same code is run both by the parent and the child then isn‟t the task done twice? It‟s the job
of the programmer to write the code in such a manner that only one of the task is done when the
parent process runs the code and the other task is done when the child runs the code.
Program for fork() system call
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t p;
printf("before fork\n");
p=fork();
if(p==0)
{
printf("I am child having id %d\n",getpid());
printf("My parent's id is %d\n",getppid());
}
else{
printf("My child's id is %d\n",p);
printf("I am parent having id %d\n",getpid());
}
printf("Common\n");
}
Output:
After compiling the program with gcc it creates an output file “a.out”. The moment you run a.out
using the command, ./a.out, a new process is created (parent). This process gets the process id
(PID) 27. The PID will differ from system to system and each time you run the program. The
process starts to run and it prints before fork. Next it executes the fork() system call. If it gets
executed a child process is created having a different PID. Now there are two process in the
system both having the same code to run. But since the code has been run till this line the
execution will continue from the next line in both the process. fork() on success returns either 0
or a non-zero value. Since, the same code is both the processes the variable „p‟ will have some
value in both the process. In the parent process it gets a non-zero positive value (which actually
is the PID of the child). In the child process „p‟ gets the value „0‟.
Hence the next lines of code has been written to check the value of „p‟. When the if-else code
runs from within the parent the condition becomes false and the else part is run. So, the lines
My child‟s id is 28
I am parent having id 27
When the if-else case runs from within the child the if condition becomes true and hence the
lines
I am child having id 28
My parent‟s id is 27
Since the printf(“common\n”) line was out of the if-else it has been printed twice; once by the
parent process and once by the child process.
By analysing the PID printed by each process the parent-child relationship can also be verified
between them. The process with PID 27 says its child has a PID 28. Similarly, the process with
PID 28 says its parent has a PID 27.
Note: The function getpid() is used to print the PID of a process while the function getppid() is
used to print the PID of the parent process.
Point to Remember:
Whatever task you want the parent to perform should be written in the else part and the task for
the child process should be written in p==0 part. Anything outside the if-else will be performed
by both parent and child.
If the code is run multiple times, the order of the output lines may differ. Since there are two
processes, the processor can be assigned to any of them. One of them can pre-empt the other and
hence the output may overlap. The order of the output will differ. If you want the parent to
execute first or the child to execute first then either wait() or sleep() functions can be used
depending on the requirement.
Program for wait() system call
When a process creates a child process, sometimes it becomes necessary that the parent process
should execute only after the child has finished. wait() system call does exactly this. It makes the
parent process wait for child process to finish and then the parent continues its working from the
statement after the wait().
To be exact wait makes the parent wait for the child to change state. The state change can be :
the child terminated; the child was stopped by a signal; or the child was resumed by a signal.
Synopsis
#include <sys/types.h>
#include <sys/wait.h>
wait() system call takes only one parameter which stores the status information of the process.
Pass NULL as the value if you do not want to know the exit status of the child process and are
simply concerned with making the parent wait for the child. On success, wait returns the PID of
the terminated child process while on failure it returns -1.
Important: wait() can be used to make the parent wait for the child to terminate(finish) but not
the other way around.
Program for wait() system call which makes the parent process wait for the child
to finish.
#include<unistd.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/wait.h>
int main()
{
pid_t p;
printf("before fork\n");
p=fork();
if(p==0)//child
{
printf("I am child having id %d\n",getpid());
printf("My parent's id is %d\n",getppid());
}
else//parent
{
wait(NULL);
printf("My child's id is %d\n",p);
printf("I am parent having id %d\n",getpid());
}
printf("Common\n");
}
Output
How it works?
The execution begins by printing “before fork”. Then fork() system call creates a child process.
wait() system call is added to the parent section of the code. Hence, the moment processor starts
processing the parent, the parent process is suspended because the very first statement is
wait(NULL). Thus, first, the child process runs, and the output lines are all corresponding to the
child process. Once the child process finishes, parent resumes and prints all its printf()
statements. The NULL inside the wait() means that we are not interested to know the status of
change of state of child process.
Program1: To create a normal child (duplicate) process (no orphan process in this case)
#include<stdio.h
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t p;
p=fork();
if(p==0) //child
{
printf("I am child having PID %d\n",getpid());
printf("My parent PID is %d\n",getppid());
}
else //parent
{
printf("I am parent having PID %d\n",getpid());
printf("My child PID is %d\n",p);
}
}
Output:
Process duplication
This is a normal duplication of process. The Parent process having PID 130 creates a child
process with PID 131.
#include<stdio.h
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t p;
p=fork();
if(p==0)
{
sleep(5); //child goes to sleep and in the mean time parent
terminates
printf("I am child having PID %d\n",getpid());
printf("My parent PID is %d\n",getppid());
}
else
{
printf("I am parent having PID %d\n",getpid());
printf("My child PID is %d\n",p);
}
}
Output:
Orphan Process
How it Works?
In this code, we add sleep(5) in the child section. This line of code makes the child process go to
sleep for 5 seconds and the parent starts executing. Since, parent process has just two lines to
print, which it does well within 5 seconds and it terminates. After 5 seconds when the child
process wakes up, its parent has already terminated and hence the child becomes an orphan
process. Hence, it prints the PID of its parent as 1 (1 means the init process has been made its
parent now) and not 138.
Note: The process will not return to the command prompt. Hence, use Ctrl+C to come to the
command prompt. What can be the possible reason?
Program
//zombie.c
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t t;
t=fork();
if(t==0)
{
printf("Child having id %d\n",getpid());
}
else
{
printf("Parent having id %d\n",getpid());
sleep(15); // Parent sleeps. Run the ps command during this time
}
}
Output:
$gcc zombie.c
$./a.out &
How it works?
Now Compile the program and run it using ./a.out &. The „&‟ sign makes it run in the
background. After you see the output of both the printf statement, note that the parent will go
into sleep for 15 seconds. During this time type the command „ps’. The output will contain a
process with defunct written in the end. Hence, this is the child process (can be verified from
PID) which has become zombie.
In order to prevent this use the wait() system call in the parent process. The wait() system call
makes the parent process wait for the child process to change state.