0% found this document useful (0 votes)
378 views7 pages

Fork Process Creation in C

The document summarizes the fork system call in Linux, which is used to create a new process called the child process. The fork call returns a process ID to both the parent and child processes. The child process is an exact duplicate of the parent process except that it has a different process ID. Multiple examples are provided to demonstrate how the parent and child processes run concurrently after a fork and can modify independent data. The number of processes created by multiple fork calls is explained to be 2 to the power of the number of fork calls.

Uploaded by

Akash Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
378 views7 pages

Fork Process Creation in C

The document summarizes the fork system call in Linux, which is used to create a new process called the child process. The fork call returns a process ID to both the parent and child processes. The child process is an exact duplicate of the parent process except that it has a different process ID. Multiple examples are provided to demonstrate how the parent and child processes run concurrently after a fork and can modify independent data. The number of processes created by multiple fork calls is explained to be 2 to the power of the number of fork calls.

Uploaded by

Akash Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Practical – 3

Objective:
Process basics: Creating processes using fork()
Description:
Fork system call is used for creating a new process, which is called child process, which runs concurrently with
the process that makes the fork() call (parent process). After a new child process is created, both processes will
execute the next instruction following the fork() system call. A child process uses the same pc(program counter),
same CPU registers, same open files which use in the parent process.

It takes no parameters and returns an integer value. Below are different values returned by fork().

Negative Value: creation of a child process was unsuccessful.


Zero: Returned to the newly created child process.
Positive value: Returned to parent or caller. The value contains process ID of newly created child process.

creating a fork process

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{

// make two process which run same


// program after this instruction
fork();
printf("Hello world!\n");
return 0;
}

Output:

Hello world!
Hello world!

Calculate number of times hello is printed:

#include <stdio.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hello\n");
return 0;
}

Output:

hello
hello
hello
hello
hello
hello
hello
hello

The number of times ‘hello’ is printed is equal to number of process created. Total Number of Processes = 2n,
where n is number of fork system calls. So here n = 3, 23 = 8
Let us put some label names for the three lines:

fork (); // Line 1


fork (); // Line 2
fork (); // Line 3

L1 // There will be 1 child process


/ \ // created by line 1.
L2 L2 // There will be 2 child processes
/ \ / \ // created by line 2
L3 L3 L3 L3 // There will be 4 child processes
// created by line 3

So there are total eight processes (new child processes and one original process).

If we want to represent the relationship between the processes as a tree hierarchy it would be the following:

The main process: P0


Processes created by the 1st fork: P1
Processes created by the 2nd fork: P2, P3
Processes created by the 3rd fork: P4, P5, P6, P7

P0
/ | \
P1 P4 P2
/ \ \
P3 P6 P5
/
P7

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample()
{
// child process because return value zero
if (fork() == 0)
printf("Hello from Child!\n");

// parent process because return value non-zero.


else
printf("Hello from Parent!\n");
}
int main()
{
forkexample();
return 0;
}

Output:

1.
Hello from Child!
Hello from Parent!
(or)
2.
Hello from Parent!
Hello from Child!

In the above code, a child process is created.


fork() returns 0 in the child process and positive integer in the parent process.
Here, two outputs are possible because the parent process and child process are running concurrently. So we don’t
know whether the OS will first give control to the parent process or the child process.

Important: Parent process and child process are running the same program, but it does not mean they are
identical. OS allocate different data and states for these two processes, and the control flow of these processes
can be different. See next example:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample()
{
int x = 1;

if (fork() == 0)
printf("Child has x = %d\n", ++x);
else
printf("Parent has x = %d\n", --x);
}
int main()
{
forkexample();
return 0;
}

Output:

Parent has x = 0
Child has x = 2
(or)
Child has x = 2
Parent has x = 0

Here, global variable change in one process does not affected two other processes because data/state of two
processes are different. And also parent and child run simultaneously so two outputs are possible.

fork() vs exec()

The fork system call creates a new process. The new process created by fork() is a copy of the current process
except for the returned value.
The exec() system call replaces the current process with a new program.

Exercise:

1. A process executes the following code:


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

The total number of child processes created is: (GATE-CS-2008)


(A) n
(B) 2^n – 1
(C) 2^n
(D) 2^(n+1) – 1;

2. Consider the following code fragment:


if (fork() == 0) {
a = a + 5;
printf("%d, %d\n", a, &a);
}
else {
a = a –5;
printf("%d, %d\n", a, &a);
}
Let u, v be the values printed by the parent process, and x, y be the values printed by the child process. Which
one of the following is TRUE? (GATE-CS-2005)
(A) u = x + 10 and v = y
(B) u = x + 10 and v != y
(C) u + 10 = x and v = y
(D) u + 10 = x and v != y

3. Predict output of below program.


#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
fork() && fork() || fork();
fork();

printf("forked\n");
return 0;
}

Common questions

Powered by AI

In this code, 'a' is independently modified in the child and parent processes due to separate memory spaces. The child process increments 'a' by 5, while the parent process decrements it by 5. Despite originating from the same initial value, the modifications occur in isolation, showcasing memory separation post-fork .

The fork() system call returns different values to the parent and child processes to differentiate between them. It returns a zero to the newly created child process, a positive value (the child's process ID) to the parent process, and a negative value in case of failure in creating a child process .

The outputs are not deterministic because the operating system schedules the parent and child processes to run concurrently, and the OS's scheduling algorithm decides which process gets CPU time first. Thus, the order in which outputs appear can vary between runs .

The output is non-deterministic due to the logical combination within 'fork() && fork() || fork();'. Each part of this expression may alter flow based on OS scheduling, resulting in several possible outcomes due to conditional execution paths and concurrent process management .

When a fork() system call is invoked, a new process is created. The total number of processes created is 2^n, where n is the number of fork() calls. This accounts for the original process and the newly forked processes. In the example provided, three fork() calls create 2^3 = 8 processes .

The sequence of 'Hello from Child!' and 'Hello from Parent!' outputs is affected by the operating system's scheduling. Both processes run concurrently but independently, leading to either order being possible depending on which process gets scheduled to run first at runtime .

The key difference is that fork() creates a new process by duplicating the calling process, while exec() replaces the current process image with a new program. Fork allows two simultaneous executions of the same code, whereas exec creates a single execution with a new code .

The correct number of child processes created in this loop is 2^n - 1. This is because each loop iteration doubles the number of processes. The zero-iteration scenario starts with one process (the parent), ending with one additional per executed loop, resulting in 2^n - 1 new children along parent instances .

Nested fork() calls exponentially increase the number of processes. Each calling fork adds a level of branching, effectively doubling processes with each subsequent call, leading to a tree structure. For example, a sequence of three fork() calls results in 2^3 = 8 total processes, demonstrating exponential growth as processes branch .

After a fork(), the parent and child processes have separate memory spaces. Changes to variables in one process do not affect the other, as each process maintains its own copy of the data. Thus, modifying 'x' in the child process to 'x = 2' does not affect the parent, which has 'x = 0' .

You might also like