The Fork System Call in Linux

Featured Image - The Fork System Call

In this article, you will find a brief description of the fork system call and how it works.

This article requires that you have some background knowledge of the concept of process in any operating system.

What is Fork System Call?

Fork() is a system call, used in Linux, whose primary purpose is to create a new process. This is done by making a copy or clone of the parent process.

[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
Note: The process which calls the fork system call is called the parent process and the clone created by calling the fork system call is known as the child process.
[/powerkit_alert]

The fork system call makes a full copy of the parent process. This means that the operating system would create a new address space for the child process (as it does for every new process). Then it will copy everything of the parent (i.e., data, registers values, code segment, and the PCB) for the child process.

Syntax of Fork system call

You can use the fork system call in your programs using the following syntax

int fork(void)

You can pass some arguments to fork system call or may leave it empty (such as fork()).

As the child process is the copy of the parent process, both would have the same code. So, let’s see how you can differentiate these copies from one another. You can distinguish them with the help of the value fork() would return.

The fork() system call may return two values: 0 or process ID. If fork() returns 0 value, its means it is the child process. On the other hand, in the parent process, fork() will return the process ID of the child process.

To clarify this concept let’s see the example below.

Example # 1

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()

{
if (fork() == 0)
{
printf("hello from child\n");
}
else{
printf("Hello from parent\n");
}
}

Since an if statement is used in the above program, only one message needs to be printed. But in the output, you will get both messages.

How this is possible? In fact, the fork system call used in the above example will create a new copy of the running process (child process) with the same code. So, in the parent process the if condition will become FALSE and message after else will get printed. But in the child process the if condition will become TRUE and the message after it will get printed. That’s why you will get two outputs from a single if-else statement.

Further explanation

A problem occurs in the situation when two processes (parent and child) are ready, and both want to print simultaneously. Since there is usually a single screen or monitor attached to the computer, the result of both processes would be displayed on the same screen.

As you may know, everything is treated as a file in Unix and all flavors of Linux. Even the hardware, such as the screen or printer, is treated as a file. This means if you want to print something, you have to write it in the respective file.

As mentioned earlier that a child process is a full copy of the parent process, which means that every feature of the parent process would be copied including its PCB, stack pointers, and even the file descriptor.

The output file of the parent which is opened by default will also be copied. In other words, the parent is now also sharing this file with the child. Both of them will write to this file so their output would be displayed on the same screen one after the other.

Example # 2

In this example, the values of the variable x will clearly show that there are two copies of the same program. It means that the fork system call has created a new process.

void fork1()
{
    int x = 1;
    pid_t pid = fork();
    if (pid == 0) {
        printf("Child has x = %d\n", ++x);
    } else {
        printf("Parent has x = %d\n", --x);
    }
    printf("Bye from process %d with x = %d\n", getpid(), x);
}

Again, the process id is used to find the difference between the parent and child processes. This is very useful when you want to do two different things from the same code. That’s the main reason for making clones in the first place.

In the above example, the variable x is initialized by one. If the process id returned by fork() is 0 (means we are in the child process), the value of x will increment by one before printing. So, the value printed in the child process will be 2.

On the other hand, if the process id returned by fork() is not 0 (means we are in the parent process), the value of x will be decremented by one in this case. So, 0 will be printed from the parent process.

Order of execution

As they are now two different programs due to the application of the fork system call, both of them will execute their statements.

But the question is which printf() statement would execute first? Remember these are two separate processes, the order of printing of both parent and child processes is not fixed.

Depending on the operating system, the process which gets the resource will be executed first. So, their order of execution is not fixed and the process getting the required resources first, will be executed first.

Example # 3

In this example, the parent process will print L0. The invocation of the fork() system call will create the first child. Now there are two processes (a parent and its child). So both of them will execute the second printf(). As a result, L1 will be printed twice, as shown in the output on the right side of the above image.

[powerkit_alert type=”info” dismissible=”false” multiline=”false”]
Note: the child process starts execution from the point where the fork() system call is issued and not from the beginning of the code.
[/powerkit_alert]

Both of these processes will now invoke the fork() system call, resulting in the creation of two new child processes. Now you have four processes in total: parent, first child, and their one child each. Consequently, all of them will print the last statement. This is evident from the output printed four times.

Example # 4

In this example, the parent process starts by printing L0 and creating a child process (say C1) using the fork() system call. The process id returned by fork() is checked and as the condition is FALSE the parent will not execute the entire if statement and will exit by printing the last line (Check the last line of the output).

However, this condition is true for the child process C1, so it will enter into the if block and will print L1. In the if condition, a second child (C2) will be created due to the use of the fork.

Just like the parent, the condition for C1 becomes false (as it is the parent of C2). Therefore, C1 will skip the inner if block and will exit by printing the last line (Check the second last line in the output).

Likewise, the condition of second if is true for C2, so this if block will execute in the copy of C2. After printing L2, a new process (C3) is created before C2 prints the last line and exits. At this point, nothing is left for C3 to do except to print the last line (Check the first and second lines in the output).

Conclusion

In this article, you have learned about the fork() system call, that you can use to create new processes in Linux. The fork system call is usually used from within a running process. Several examples are shown in this article to clarify this concept, but if you still have questions or feedback then feel free to let us know and we’ll get back to you as soon as we can.

0 Shares:
Subscribe
Notify of
guest
Receive notifications when your comment receives a reply. (Optional)
Your username will link to your website. (Optional)

0 Comments
Inline Feedbacks
View all comments
You May Also Like
Touch Command in Linux
Read More

Touch Command in Linux

Creating files is one of the most common things we do. Every now and then, you may also…