Fork in C

Last updated by Ashwin Ramachandran on Sep 25, 2024 at 10:59 PM
Contents

In this article, we’ll discuss the concept of fork system call. Some experience with Unix or other operating systems like it and experience in C/C++ will help one understand this article better. We’ll learn:

  • What’s a Process?
  • What Does fork() Mean?
  • The fork() Function
  • Examples
  • FAQs on Fork in C

What’s a Process?

A process refers to an actively executing program. That’s not to say that a process is just the code that’s running. A process also includes the process stack, counter, registers, etc., that’s associated with the process, which a process control block stores.

The creation of all the processes other than the startup process requires executing the fork system call in an operating system. The parent process is the process that uses the fork() function. And any process created by a parent using a fork system call is referred to as a child process.

A parent process can have many child processes, but a child process can have only one parent process. If a child process does not have a parent process, the kernel was directly responsible for creating it. And if a parent process closes or crashes for any reason, it kills the child process.

What Does fork() Mean?

Before we understand the fork function, it is worthwhile to define what fork means. In the context of routes, fork, as a verb, refers to dividing a path into two. Example: “The road forks here.” means the original road splits into two lanes from here. In the context of languages like C, C++, shell script, etc., fork refers to something similar in essence: Creating a child process by duplicating a parent process, and then they both run concurrently. Let’s now see how this works.

The fork() Function

We use the fork() system call to create a new process from the calling process by duplicating it. The parent process does the fork() system call, and its child process is formed as a result of that call if it’s successful.

The fork() function does not take any arguments. It just creates a child process and returns a process ID. If a fork call is successful:

  • The OS will make two identical copies of address spaces for parent and child processes. So the parent and child processes have different address spaces.
  • A local variable is:
    1. Declared inside the process
    2. Created when the process starts
    3. Lost when the process terminates
  • A global variable is:
    1. Declared outside the process
    2. Created as the process starts
    3. Lost when the program ends
  • The process ID, i.e., PID of the child process created, is returned to the parent process. (In case of failure, -1 is returned to the parent process.)
  • Zero is returned to the child process. (If it fails, the child process is not created.) If a child process exits at that instant or is interrupted, a signal SIGCHLD is sent to the parent process.
  • Both parent and child processes independently execute the subsequent commands after the fork() system call.

Using the information above, we can use the value fork returns to distinguish between parent and child processes:

  • Negative value: The fork call failed.
  • Zero value: This value is returned to the child that has been newly created.
  • Positive value: The parent received the PID of the child process as the return value.

Examples

The best way to understand fork() calls further would be through some examples. Let’s jump right in!

Example 1

In this example, we show that after fork(), if the call is successful, the parent and the child processes run concurrently.

#include <stdio.h>

int main()

{

    fork();

    printf(“If the fork function is successful in creating a child process, I will print twice.n”);

    return 0;

}

Output:

If the fork function is successful in creating a child process, I will print twice.

If the fork function is successful in creating a child process, I will print twice.

Example 2

In this example, we focus on getting process IDs and again show that both parent and child run concurrently after a successful fork system call.

#include <stdio.h>

int main()

{

    int processID= fork();

    if(processID>0)

    {

        printf(“fork() returned a +ve value. This is the parent process, with ID: %d n”,getpid());

    }

    else if(processID==0)

    {

        printf(“fork() returned a 0 value. This is a newly created child process with ID: %d n”,getpid());

        printf(“The parent process of this child process has the ID: %dn”,getppid());

    }

    else

    {

        printf(“fork() returned a -ve value, so the fork system called failed and the child process could not be createdn”);

    }

    printf(“This is a single print statement. If the fork() system call was successful, both the parent and child process will run concurrently, and this statement will print twice.n”);

    return 0;

}

Output:

fork() returned a +ve value. This is the parent process, with ID: 25285

This is a single print statement. If the fork() system call was successful, both the parent and child process will run concurrently, and this statement will print twice.

fork() returned a 0 value. This is a newly created child process with ID: 25505

The parent process of this child process has the ID: 1

This is a single print statement. If the fork() system call was successful, both the parent and child process will run concurrently, and this statement will print twice.

If the PPID is 1, it means the parent process terminated before the child process. And the PPID of the child got updated to 1 as init became the new parent. The output of the examples we see here may vary depending on if the parent process gets terminated before or after the child process. If needed, we can use more advanced concepts like “wait” and “status” to ensure the parent doesn’t end before the child.

Example 3

In this example, we do multiple fork calls and show that the number of times a statement is run after the calls is equal to  2^N, where N is the number of fork() system calls we’ve made. Here, the number of child processes created is equal to 2^N-1.

#include <stdio.h>

int main()

{

    fork();

    fork();

    fork();

    printf(“The fork function was called three times. I should print eight times.n”);

    return 0;

}

Output:

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

The fork function was called three times. I should print eight times.

We get this output when no parent terminates before its children. Here, the number of times the line gets printed may change if a parent terminates before its children. We may, as mentioned earlier, use concepts like “wait” and “status” to ensure no parent terminates before its children.

FAQs on Fork in C

{“@context”:”https://schema.org”,”@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”Will the parent or the child process execute the statement after the fork() call first?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”The parent and the child process are running concurrently, and the OS could grant control to either of them first. Therefore, either of them could run the statement after the fork() call first.”}}]}

Question 1: Will the parent or the child process execute the statement after the fork() call first?

The parent and the child process are running concurrently, and the OS could grant control to either of them first. Therefore, either of them could run the statement after the fork() call first.

Question 2: What’s the difference between fork() and exec() function in C?

Recommended Reading

Are you a software engineer looking for coding interview questions to aid your technical interview prep? Check out these informative pages for software developers:

Are You Ready to Nail Your Next Coding Interview?

Whether you’re a Coding Engineer gunning for Software Developer or Software Engineer roles, or you’re targeting management positions at top companies, IK offers courses specifically designed for your needs to help you with your technical interview preparation!

If you’re looking for guidance and help with getting started, sign up for our free webinar. As pioneers in the field of technical interview prep, we have trained thousands of Software Engineers to crack the most challenging coding interviews and land jobs at their dream companies, such as Google, Facebook, Apple, Netflix, Amazon, and more!

Sign up now!

————

Article contributed by Tanya Shrivastava

Last updated on: September 25, 2024
Author
Ashwin Ramachandran
Head of Engineering @ Interview Kickstart. Enjoys cutting through the noise and finding patterns.
Register for our webinar

Uplevel your career with AI/ML/GenAI

Loading_icon
Loading...
1 Enter details
2 Select webinar slot
By sharing your contact details, you agree to our privacy policy.

Select a Date

Time slots

Time Zone:

Spring vs Spring Boot

Spring vs Spring Boot: Simplifying Java Application Development

Reinforcement Learning: Teaching Machines to Make Optimal Decisions

Reinforcement Learning: Teaching Machines to Make Optimal Decisions

Product Marketing vs Product Management

Product Marketing vs Product Management

Java Scanner reset()

The upper() Function in Python

Insertion Sort Algorithm

Ready to Enroll?

Get your enrollment process started by registering for a Pre-enrollment Webinar with one of our Founders.

Next webinar starts in

00
DAYS
:
00
HR
:
00
MINS
:
00
SEC

Register for our webinar

How to Nail your next Technical Interview

Loading_icon
Loading...
1 Enter details
2 Select slot
By sharing your contact details, you agree to our privacy policy.

Select a Date

Time slots

Time Zone:

Get tech interview-ready to navigate a tough job market

Best suitable for: Software Professionals with 5+ years of exprerience
Register for our FREE Webinar

Next webinar starts in

00
DAYS
:
00
HR
:
00
MINS
:
00
SEC