7.3.4 Distinguishing Between Parent and Child Processes
7.3.4 Distinguishing Between Parent and Child Processes
In addition to creating a child process, fork returns an ID to the parent and the child. The child process that is created gets a value of 0 from fork. The parent process that created the child gets a non-zero value from fork. This is the identification number for the child that is created. If fork fails, it returns undef to the parent process. If forking
fails, there is no child process. forking can fail because of reasons such as too many processes in the system, whether running or not.
The following program tests the idea that fork returns a separate value to each of the processes.
Program 7.18
#!/usr/bin/perl use strict; my $processID; print "Before forking\n"; #fork returns a process ID number to the parent and another to the child $processID = fork (); print "My process ID number = $processID\n";
After fork we have two processes running. So, the print statement at the end of the program is executed by each of these two processes. But, because fork returns a different number to each of the two processes, the two processes print two different numbers. The output of a run of the program is given below.
Before forking My process ID number = 32350 My process ID number = 0
The fact that fork returns a different number to the parent and the child processes can be used to distinguish one from the other. That is, the program code can have a conditional that checks for the returned value to tell one process from the other. The following is a simple program that performs such a conditional test.
Program 7.19
#!/usr/bin/perl
use strict;
my ($childProcessID);
print "I AM THE ONLY PROCESS.\n";
$childProcessID = fork ();
if ($childProcessID){
print "I am the parent process.\n";
}
else{
print "I am the child process.\n";
}
Before the call to fork, there is only one process. It the prints
I AM THE ONLY PROCESS.
to announce itself to the world. Next, we have the call that creates a child process.
$childProcessID = fork ();
Following this line of code, we have an if-else statement. We have two processes running at this time. Both processes execute the if-else statement. The $childProcessID variable is available to both processes. However, $childProcessID has a non-zero value when examined by the parent process, and is zero when examined by the child process. Although the variable name is shared, each process has its own separate copy of the variable. In particular, there are two copies of
$childProcessID for the two processes. For one process (the child), the associated value is 0, whereas it is non-zero for the other (the parent). For the parent, the value stored is the process ID of the child process. Because each process is associated with an ID, processes are able to communicate with one another, as we see later.
In this program, both processes are printing to STDOUT. These two processes run in parallel. Therefore, when we run the program, in some cases,
I am the child process.
is printed before the string
I am the parent process.
is printed.
In this program, the two processes are not very long-lived. After printing
I am the parent process.
the parent process has nothing more to do as there is no line of code following the if-else statement. Therefore, after printing the, the parent process is finished or dies naturally. Similarly, the child process is also finished after it prints its own string:
I am the child process.
After this string is printed, the child process has no additional lines of code to execute because it also reaches the end of the program.
In this program, there is no way to tell which process prints first and which process prints second. In addition, there is no way to tell which process ends first and which process ends next. The two processes have independent lives after the child process has been forked. They perform their actions independently although the instructions they follow are the same. They do so without communicating with each other. Since the amount of code in our program after the call to fork() is very small, everything happens fast. Therefore, it is most likely that the parent process does its printing before the child process.
The next program we discuss is a slight variation of the previous program. The only difference is that once a child process has been forked, each of the two existing processes runs a little longer than before and produces more output. It is because we have a small for loop inside the if block as well as inside the else block.
Program 7.20
#!/usr/bin/perl
use strict;
my ($childProcessID, $i);
print "I AM THE ONLY PROCESS.\n";
$childProcessID = fork ();
if ($childProcessID){
for ($i = 0; $i <= 10; $i++){
print "I am the parent process: Counting $i\n";
}
}
else{
for ($i = 0; $i <= 10; $i++){
print "I am the child process: Counting $i\n";
}
}
Because the two processes run in parallel, have independent existence, and do not synchronize their actions, the output of the program is intermixed between what the two processes print to STDOUT. Each process counts sequentially, but the two counts are interwoven. A possible output of the program to STDOUT is given below.
I AM THE ONLY PROCESS. I am the parent process: Counting 0 I am the parent process: Counting 1 I am the child process: Counting 0 I am the child process: Counting 1 I am the child process: Counting 2 I am the child process: Counting 3 I am the child process: Counting 4 I am the child process: Counting 5 I am the child process: Counting 6 I am the child process: Counting 7 I am the parent process: Counting 2 I am the parent process: Counting 3 I am the parent process: Counting 4 I am the parent process: Counting 5 I am the parent process: Counting 6 I am the parent process: Counting 7 I am the parent process: Counting 8 I am the parent process: Counting 9 I am the parent process: Counting 10 I am the child process: Counting 8 I am the child process: Counting 9 I am the child process: Counting 10
