Unix Multiprocess Programming: 1 The Fork System Call
Unix Multiprocess Programming: 1 The Fork System Call
fork() returns a positive value, the process ID of the child process, to the
parent. The returned process ID is of type pid t defined in sys/types.h.
Normally, the process ID is an integer. Moreover, a process can use func-
tion getpid() to retrieve the process ID assigned to this process.
Therefore, after the system call to fork(), a simple test can tell which process
is the child. Please note that Unix will make an exact copy of the parents
address space and give it to the child. Therefore, the parent and child processes
have separate address spaces.
Let us take an example to make the above points clear. This example does
not distinguish parent and the child processes. Click here to download this file
fork-01.c.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void main(void)
{
pid_t pid;
int i;
char buf[BUF_SIZE];
1
Figure 1: Call fork() function
fork();
pid = getpid();
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
write(1, buf, strlen(buf));
}
}
Suppose the above program executes up to the point of the call to fork()
(marked in red color):
If the call to fork() is executed successfully, Unix will
Make two identical copies of address spaces, one for the parent and the
other for the child.
Both processes will start their execution at the next statement following
the fork() call. In this case, both processes will start their execution at
the assignment statement as shown below:
Both processes start their execution right after the system call fork(). Since
both processes have identical but separate address spaces, those variables initial-
ized before the fork() call have the same values in both address spaces. Since
every process has its own address space, any modifications will be independent
of the others. In other words, if the parent changes the value of its variable, the
modification will only affect the variable in the parent processs address space.
Other address spaces created by fork() calls will not be affected even though
they have identical variable names.
What is the reason of using write rather than printf ? It is because printf()
is buffered, meaning printf() will group the output of a process together.
While buffering the output for the parent process, the child may also use printf
2
Figure 2: After call of fork() function
to print out some information, which will also be buffered. As a result, since
the output will not be send to screen immediately, you may not get the right
order of the expected result. Worse, the output from the two processes may be
mixed in strange ways. To overcome this problem, you may consider to use the
unbuffered write.
If you run this program, you might see the following on the screen:
................
This line is from pid 3456, value 13
This line is from pid 3456, value 14
................
This line is from pid 3456, value 20
This line is from pid 4617, value 100
This line is from pid 4617, value 101
................
This line is from pid 3456, value 21
This line is from pid 3456, value 22
................
Process ID 3456 may be the one assigned to the parent or the child. Due
to the fact that these processes are run concurrently, their output lines are
intermixed in a rather unpredictable way. Moreover, the order of these lines are
determined by the CPU scheduler. Hence, if you run this program again, you
may get a totally different result.
Consider one more simple example, which distinguishes the parent from the
child. Click here to download this file fork-02.c.
#include <stdio.h>
#include <sys/types.h>
void main(void)
{
pid_t pid;
3
pid = fork();
if (pid == 0)
ChildProcess();
else
ParentProcess();
}
void ChildProcess(void)
{
int i;
void ParentProcess(void)
{
int i;
4
Figure 3: Pid values