UNIX / Linux Processes: C fork() Function

by Himanshu Arora on May 18, 2012

Every running instance of a program is known as a process. The concept of processes is fundamental to the UNIX / Linux operating systems. A process has its own identity in form of a PID or a process ID. This PID for each process is unique across the whole operating system. Also, each process has its own process address space where memory segments like code segment, data segment, stack segment etc are placed. The concept of process is very vast and can be broadly classified into process creation, process execution and process termination.

Linux Processes Series: part 1, part 2, part 3, part 4 (this article).

In this article we will concentrate on the process creation aspect from programming point of view. We will focus on the fork() function and understand how it works.

The fork() Function

The fork() function is used to create a new process by duplicating the existing process from which it is called. The existing process from which this function is called becomes the parent process and the newly created process becomes the child process. As already stated that child is a duplicate copy of the parent but there are some exceptions to it.

  • The child has a unique PID like any other process running in the operating system.
  • The child has a parent process ID which is same as the PID of the process that created it.
  • Resource utilization and CPU time counters are reset to zero in child process.
  • Set of pending signals in child is empty.
  • Child does not inherit any timers from its parent

Note that the above list is not exhaustive. There are a whole lot of points mentioned in the man page of fork(). I’d strongly recommend readers of this article to go through those points in the man page of fork() function.

The Return Type

Fork() has an interesting behavior while returning to the calling method. If the fork() function is successful then it returns twice. Once it returns in the child process with return value ’0′ and then it returns in the parent process with child’s PID as return value. This behavior is because of the fact that once the fork is called, child process is  created and since the child process  shares the text segment with parent process and continues execution from the next statement in the same text segment so fork returns twice (once in parent and once in child).

C Fork Example

Lets take an example to illustrate the use of fork function.

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>

int var_glb; /* A global variable*/

int main(void)
{
    pid_t childPID;
    int var_lcl = 0;

    childPID = fork();

    if(childPID >= 0) // fork was successful
    {
        if(childPID == 0) // child process
        {
            var_lcl++;
            var_glb++;
            printf("\n Child Process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
        else //Parent process
        {
            var_lcl = 10;
            var_glb = 20;
            printf("\n Parent process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
    }
    else // fork failed
    {
        printf("\n Fork failed, quitting!!!!!!\n");
        return 1;
    }

    return 0;
}

In the code above :

  • A local and a global variable  (var_lcl and var_glb ) declared and initialized with value ’0′
  • Next the fork() function is called and its return value is saved in variable childPID.
  • Now, the value of childPID is checked to make sure that the fork() function passed.
  • Next on the basis of the value of childPID, the code for parent and child is executed.
  • One thing to note here is why the variables var_lcl and var_glb are used?
  • They are used to show that both child and parent process work on separate copies of these variables.
  • Separate values of these variables are used to show the above stated fact.
  • In linux, a copy-on-write mechanism is used where-in both the child and the parent keep working on the same copy of variable until one of them tries to change its value.
  • After fork, whether the child will run first or parent depends upon the scheduler.

Now, when the above code is compiled and run :

$ ./fork

Parent process :: var_lcl = [10], var_glb[20]

Child Process :: var_lcl = [1], var_glb[1]

We see that in the output above, both the child and parent process got executed and logs show separate values of var_lcl and var_glb. This concludes that both parent and child had their own copy of var_lcl and var_glb.

NOTE: A function getpid() can be used to fetch the process ID of the calling process and the function getppid() can be used to fetch the PID of the parent process.


Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 17 comments… read them below or add one }

1 Jalal Hajigholamali May 18, 2012 at 5:59 am

Hi,

Thanks a lot..
Very nice and practical article….

2 Marco May 18, 2012 at 6:35 pm

I keep following you! This blog is a must for CS students and enthusiasts!

3 Nawar May 23, 2012 at 4:00 pm

I like your articles very much and a great FAN of TGS.

4 subbarao October 6, 2012 at 5:14 am

very nice one

5 Greg October 22, 2012 at 5:31 am

Good article thanks for the post!

6 alex November 14, 2012 at 4:48 pm

First and foremost i like this blog!!, However, I have two questions about the child parent topic.

int main(void) {
int i;
fork();
fork();
fork();
printf(“process…\n”);
return 0;
}
i have such a program. whenever i run it, i get 8 process… es. why? how many children are here. and how many parents do we have? can i have them as a tree diagram?

Thanks in advance

7 Joe January 28, 2013 at 4:39 pm

You have 8 processes because fork creates an additional process for the parent and child. The program starts with 1. You call fork() now you have 2. Call fork() again and you have 4. Call fork() a third time and you have 8. Here’s the best diagram i can do here on this text editor. The children are below the parent on each level of the hierarchy:

1
2 4 5
3 6 7
8

As you can see the left side will always be bigger because the 2nd process was created there first.

8 Joe January 28, 2013 at 4:40 pm

okay it didn’t keep my spaces and the formatting of my tree did not show up, but just step through it and i’m sure you’ll be able to figure it out.

9 RedSin March 9, 2013 at 7:18 pm

perfect, I never understand fork() until read you explain, function return twice is so new for me.

Thanks alot

10 Filipe Souza March 20, 2013 at 8:51 am

Hello,

Nice article.

I have one doubt about what I did here in my code:

if(childPID == 0) // child process
{
var_lcl++;
var_glb++;
printf(“\n Child Process :: var_lcl = [%d], var_glb[%d]\n”, var_lcl, var_glb);
printf(“child\n”);
int pid = getpid();
int parent_pid = getppid();
printf(“My real pid is %d\n”, pid);
printf(“My parent pid is %d\n”, parent_pid);
}
else //Parent process
{
var_lcl = 10;
var_glb = 20;
printf(“\n Parent process :: var_lcl = [%d], var_glb[%d]\n”, var_lcl, var_glb);
printf(“parent\n”);
printf(“o childPID eh: %d, “,childPID);
int pid = getpid();
int parent_pid = getppid();
printf(“My real pid is %d\n”, pid);
printf(“My parent pid is %d\n\n\n\n”, parent_pid);
}

My output started with:
Parent process :: var_lcl = …….
Child Process :: var_lcl = …….

My expected output:
Parent process :: var_lcl = …….

11 shahida June 8, 2013 at 12:57 pm

AOA
thanks a lot . I really clarify my concept after reading it

12 Danish July 9, 2013 at 10:30 pm

Hi ..
Can you tel me how many processes will be created for below program and explanation will be appreciated.

main()
{

for(i=1;i<n;i++)
fork();

}

13 Angel July 22, 2013 at 4:04 pm

@Danish
I am not a Linux programer, neither havent tested yet the code that you proposed, but it kinda gives me the impression that the code is going to create an infinite set of processes (I am just taking a guess here). The cause of my assumption is because supposing fork initilized all identifiers, then, the identifier “i” in the “for” loop would be initialized to 1 each time a new process is created, thus, creating either a inifinite set of processes or making the system to throw an out of memory exception (which would be a nice feature in such case). But I am just guessing since I havent tested the code and because it seems kinda dangerous.

14 Anonymous August 6, 2013 at 7:54 pm

still now i am not able to understand that how many childs are created when we call fork()

15 renuga August 6, 2013 at 7:59 pm

main()
{
printf(“the process id is %d”,&getpid());
fork();
printf(“the child id is %d”,getpid());
}

i want to know whats d output???????explain it…….

16 Yukta September 24, 2013 at 8:16 am

plz explain me this answer

for(i=0;i<4;i++)
{
fork();
}
num of child processes created
plz let me know answer

17 Bhaskar Gautam October 28, 2013 at 1:31 pm

reply to your answer
when fork function executes it creates the copy of all process(to understand the concept you may think that it create the copy of process which are below the calling function) and continue its execution from the process which are copied.
below here is the working
when 1st fork execute it creates copy of 2 fork function and 1 printf function(say we name it as page 1st) and control will transfer to page 1st
then when 2nd fork executes from page 1st, it creates copies of 1fork function and 1 printf function (say name it as page 2nd) and control will transfer to page 2nd.
when 3rd fork function executes from page 2nd,it creates copies of 1 printf function and create a page 3rd and control will transfer to page 3rd.
So from here(i.e page 3rd) it executes 1st printf function and return it control to page 2nd.In page 2,3rd fork function executes then it executes 2nd printf function and control will transfer to page 1st.
In page 1st 2nd fork executes completely,then it comes to 3rd fork function (i.e it create 4th page) and executes 3rd printf function and comes to page 1st and executes 4th printf function and then return to main
then 2nd fork executes…..same proces is done
it create 5th page which contain 1 fork and 1 printf function and control come to 1st fork function of page 5 and executes it then it create 6 th page from which it executes printf function( which is 5th) and return to page 5th and executes printf function(which is in 6th number) and control will return to main
Then executes 3rd fork function which create 7th page from which it have 1 printf function and executes it (which is of 7th) and return to main
then it printf last printf function which is of 8th in number…….

Leave a Comment

Previous post:

Next post: