Sunday, November 6, 2011

Parent and Child Processes of C Under Linux in C programming

As we know, our running program is a process. From this process we can create another process. There is a parent-child relationship between the two processes. The way to achieve this is by using a library function called fork( ). This function splits the running process into two processes, the existing one is known as parent and the new process is known as child. Here is a program that demonstrates this

# include <sys/types.h>
int main( )
{
printf ( "Before Forking\n" ) ;
fork( ) ;
printf ( "After Forking\n" ) ;
}
Here is the output of the program…
Before Forking
After Forking
After Forking

Watch the output of the program. You can notice that all the statements after the fork( ) are executed twice—once by the parent process and second time by the child process. In other words fork( ) has managed to split our process into two.

But why on earth would we like to do this? At times we want our program to perform two jobs simultaneously. Since these jobs may be inter-related we may not want to create two different programs to perform them. Let me give you an example. Suppose we want perform two jobs—copy contents of source file to target file and display an animated GIF file indicating that the file copy is in progress. The GIF file should continue to play till file copy is taking place. Once the copying is over the playing of the GIF file should be stopped. Since both these jobs are inter-related they cannot be performed in two different programs. Also, they cannot be performed one after another. Both jobs should be performed simultaneously.

At such times we would want to use fork( ) to create a child process and then write the program in such a manner that file copy is done by the parent and displaying of animated GIF file is done by the child process. The following program shows how this can be achieved. Note that the issue here is to show how to perform two different but inter-related jobs simultaneously. Hence I have skipped the actual code for file copying and playing the animated GIF file.

# include <sys/types.h>
int main( )
{
int pid ;
pid = fork( ) ;
if ( pid == 0 )
{
printf ( "In child process\n" ) ;
/* code to play animated GIF file */
}
else
{
printf ( "In parent process\n" ) ;
/* code to copy file */
}
}

As we know, fork( ) creates a child process and duplicates the code of the parent process in the child process. There onwards the execution of the fork( ) function continues in both the processes. Thus the duplication code inside fork( ) is executed once, whereas the remaining code inside it is executed in both the parent as well as the child process. Hence control would come back from fork( ) twice, even though it is actually called only once. When control returns from fork( ) of the parent process it returns the PID of the child process, whereas when control returns from fork( ) of the child process it always returns a 0. This can be exploited by our program to segregate the code that we want to execute in the parent process from the code that we want to execute in the child process. We have done this in our program using an if statement. In the parent process the ‘else block’ would get executed, whereas in the child process the ‘if block’ would get executed.

Let us now write one more program. This program would use the fork( ) call to create a child process. In the child process we would print the PID of child and its parent, whereas in the parent process we would print the PID of the parent and its child. Here is the program…

# include <sys/types.h>
int main( )
{
int pid ;
pid = fork( ) ;
if ( pid == 0 )
{
printf ( "Child : Hello I am the child process\n" ) ;
printf ( "Child : Child’s PID: %d\n", getpid( ) ) ;
printf ( "Child : Parent’s PID: %d\n”, getppid( ) ) ;
}
else
{
printf ( "Parent : Hello I am the parent process\n" ) ;
printf ( "Parent : Parent’s PID: %d\n”, getpid( ) ) ;
printf ( "Parent : Child’s PID: %d\n", pid ) ;
}
}
Given below is the output of the program:
Child : Hello I am the child process
Child : Child's PID: 4706
Child : Parent's PID: 4705
Parent : Hello I am the Parent process
Parent : Parent's PID: 4705
Parent : Child's PID: 4706

In addition to getpid( ) there is another related function that we have used in this program—getppid( ). As the name suggests, this function returns the PID of the parent of the calling process.

You can tally the PIDs from the output and convince yourself that you have understood the fork( ) function well. A lot of things that follow use the fork( ) function. So make sure that you understand it thoroughly.

Note that even Linux internally uses fork( ) to create new child processes. Thus there is a inverted tree like structure of all the processes running in memory. The father of all these processes is a process called init. If we want to get a list of all the running processes in memory we can do so using the ps command as shown below

# ps –A

Here the switch –A indicates that we want to list all the running processes.

No comments:

Post a Comment