Fork( ) System Call
Single Concept Learning Module
The objective of this module is to introduce students to the fork system call. After the audience has listened to the lecture and executed the sample program, students will have the ability to develop multi - process programs.
I. Fork definition.
II. Process Creation.
III. Process Assignment.
IV. Example.
V. Discussion.
Concept Hours:3
The fork() System Call
I. Fork definition
To create a new process, in UNIX, the fork() system call is used. Fork() creates a new context based on the context of the calling process. The fork() call is unusual in that it returns twice: It returns in both the process calling fork() and in the newly created process. The child process returns zero and the parent process returns a number greater then zero.
The synopsis for fork() is as follows:
#include
pid_t fork(void);
pid_t vfork(void);
If fork() is successful, it returns a number of type pid_t which is greater than 0 and represents the PID of the newly created child process. In the child process, fork() returns 0. If fork() fails then its return value will be less than 0. vfork() is a m ore efficient version of fork(), which does not duplicate the entire parent context.
A example of fork() follows. Here, the parent process prints Hello to stdout, and the new child process prints World. Note that the order of printing is not guaranteed. Without some method of synchronizing the processes execution, Hello may or may not be printed before World.
#include
#include
char string1[] = "\n Hello";
char string2[] = " CS560.\n";
int main(void)
{
pid_t PID;
PID = fork();
if (PID == 0) /* Child process */
printf("%s", string2);
else /* Parent process */
printf("%s", string1);
exit(0); /* Executed by both processes */
}
The fork() creates a copy of the process that was executing. The fork() is called once but returns twice (once in the parent and once in the child).
The line PID = fork(); returns the value of the fork() system call. The if (PID == 0) evaluates the return value. If PID is equal to zero then printf() is executed in the child process, but not in the parent process.
The else part of the condition is executed in the parent process and the child process but only the parent process will execute the else part of the condition.
The child process can obtain the process ID of the parent by using the getppid system call. Below is an example of the fork and getppid system calls.
#include
void
main(void)
{
int childpid;
if( (childpid = fork() ) == -1)
{
printf("\n Can't fork.\n");
exit(0);
}
else
if(childpid == 0)
{ /* Child process */
printf("\n Child: Child pid = %d, Parent pid = %d \n", getpid(), getppid());
exit(0);
}
else
{ /* Parent Process */
printf("\n Parent: Child pid = %d, Parent pid = %d \n", childpid, getpid());
exit(0);
}
}
One important feature of the fork system call is that the files that were open in the parent process before the fork are shared by the child process after the fork. This feature allows the parent to pass open file handles and device driver handles to th e child.
The values of the following variables are copied from the parent process to the child process.
· real user ID
· real group
· effective user ID
· effective group ID
· process group ID
· terminal group ID
· root directory
· current working directory
· signal handling settings
· file mode creation mask
· the child process has a new, unique process ID,
· the child process has a different parent process ID,
· the child process has its own copies of the parent's file descriptors,
· the time left until an alarm clock signal is set to zero in the child.
1. A process wants to make a copy of itself so that one copy can handle an operation while the other copy does another task.
2. A process wants to execute another program. Since the only way to create a new process is with the fork operation, the process must first fork to make a copy of itself, then one of the copies issues an exec system call operation to execute a new program. This is typical for programs such as shells.