Hello and welcome.
In this video session, let's discuss how to create a new process.
In the previous video sessions we have discussed some basics of process like process ID and we had discussed
the virtual memory of a process.
Now let's discuss how to create a process.
Fork is the system call that is used to create a process.
We will discuss what is a child and the parent process, and the memory segment of parent and the child
process.
The main intention of creating a process is that we can break down a given bigger task into smaller
task, and allow each process to accomplish the smaller task.
This also helps in having a good software design and also provides concurrency.
That is, many processes can concurrently run together.
The fork system call creates a new process in the memory.
The new process created is called as the child process, and the process which creates the child process
is called as the parent process.
So initially after the fork is executed, a child process is created and it has exact duplicate memory
of a parent process.
Let us see how to use fork system call.
In order to use fork system call, we need to include Unistd.h.
And as seen here, the fork takes no parameter but returns the id in fork system call.
If a fork system call is success, then the process which called the fork spawns or creates a new process
called as the child process and the fork returns twice.
That is, once it returns in the parent process.
And.
Secondly, it returns in the child process.
In the parent process, the fork returns the process ID of the child.
In the child process.
When the fork is successful, the fork returns a zero.
If a fork fails, then it returns a minus one and no new process is created.
We will discuss this with the example code so that our understanding will be clear.
Now let us see a diagram to understand.
Fork system call.
Let us say this is a parent process.
This is before calling fork.
And this is a virtual memory of parent process.
And at some point in code.
Let's say the parent process executed a fork system call.
As soon as the fork system call is executed and if the fork system call is successful, we have two
processes in memory.
One will be the same parent process and other will be the child process.
As a result, this is the virtual memory of child process and this will be the virtual memory of the
parent process.
In parent process, fork returns the ID of the child process, whereas in child process fork returns
zero.
We will see this with some examples.
A important point of the fork is executed successfully.
Two process exits in memory.
One is the parent process who called it, and the other is the child process which is created after
fork.
Now each of these processes executes after the point where fork returns, the child process has a separate
copy of the virtual memory like the text segment, the data segment, and the stack segment and the
heap segment.
The child process executes the same program as the parent process.
This is because the child now has the same copy of the text segment that is present in the text segment
of the parent process, and the text segment holds the program that is present in the parent process.
The data segment of the child's memory is an exact duplicate of the parent's data segment memory, so
each process that is parent and child can modify the memory in its virtual memory like stack data and
heap segment without affecting the other process.
Let's go back to the diagram here.
Each process will have a separate virtual memory so that any changes on the data it occurs is in the
virtual space of that process.
So if any memory change occurs in parent process, it will be affected in virtual memory of the parent
process only.
And if any data manipulation occurs in the child process, that value will be affected in the virtual
memory of the child process only.
Now let us see some examples in order to understand this.
This is a simple program.
Here we are including the required header files and we begin the program from main function.
And now initially let us say this is the text segment that we have.
So this is the parent process executing.
And here we display the PID of the process which is executing initially.
And at some point we call a fork system call.
So the main thing here is often the fork system call is executed successfully.
At this point, we can think that we have the same program running twice in the memory in parent.
It executes from this point and in child also, it executes from this point.
So we can consider that the creator of the child process is the parent and the parent and the child
has the same text segment that is the same program in its virtual space.
So we will execute this and let's see the output so that our understanding will be better.
Let's compile the program now gcc four dot c hyphen 041.
Now we have compiled successfully.
Now let's run this to see the output as a note as soon as we execute a program, there will be a process
created.
So in this case, by default when we execute this program, a process is created.
Let's call this as a parent process.
And when parent process calls fork system call a new child process is created in memory.
If we see here the process created before fork is parent process and the PID of parent process is given
here.
So this is the PID that is obtained at runtime.
And this PID may change from execution to execution.
Let's say that the parent process has created child process.
With this PID.
After fork is successful, the complete text segment from parent process is duplicated in child process
as well.
Once the fork is successful, both child and parent can execute.
In parent process.
The fork returns the child process ID, whereas in child process this ID will be zero.
In case fork was not success in parent process, then child process will not be created and the fork
returns minus one.
Also, it is important to note that the child process only starts to execute the lines of the code only
after the fork.
The code before fork will not be executed in child process.
Let us quickly open the manual page of fork to check our discussion.
This is the syntax of fork system call, and if we see the return value here, it states on success.
The PID of the child process is returned in the parent and zero is returned in the child on failure,
minus one is returned in the parent.
No child process is created and errno is set appropriately.
This means after fork is success, child process is created, and in parent process fork returns PID
of child and in child process, fork returns zero.
And if fork system call is failed, fork returns minus one to parent process and no child process is
created.
Let's go back to our code.
So in our case we got the print.
That is the parent process has created the child process.
If ID is greater than zero that means this is the parent process executing.
And the fork returns the ID of the child process.
And we are displaying the child process ID here we have displayed that the parent has created a child
process and the child process ID is this And the parent process ID is this.
Now, since the same set of code is being executed by the child as well, in the child code, the ID
will be zero as four returns, zero in child process.
So this part from here to here will not be executed.
Child process starts execution from here.
That is else part and it will print these lines of codes.
I am a child process and it will display ID variable value equal to zero.
This is the variable where the fourth returned value is stored.
And in child process the ID is zero.
As a summary in child process, the fourth returns is zero and child process starts to execute only
after four system call and in parent process, fork returns the PID of the child that is created newly.
Finally, using git pad, we can get the PID of the running process.
So now we can see that child process ID is this which is obtained from git PID.
And if we observe this id will be the same as what is returned from the fork in the parent process.
So in the parent process the fork returns the child process ID we have get PID, which is it gets the
parent PID that is in this code, which is the child process.
Get PID will get the process ID of the parent from which the child process is created.
If we see both PID obtained in parent process here in start of the main and get PID in child process
or sing.
This three lines are being executed in the child process and this line is executed in parent process.
So the highlighting point here is when we run this program initially before fork, there is only one
virtual memory that is the parent process.
And once the fork is called successfully we have two processes and two virtual memory after fork.
So in this next example we will see the memory segment of a child and the parent process.
So here we include the required header files.
We have a global data called as g data and its value is 111.
We have just kept some random values.
We have a local variable called I stack stored in stack segment and its value is 2 to 2.
And now, at some point, the main process calls a fork in the parent process.
Fork returns the process ID of the child and there will be two sets of virtual memory.
One is the parent process virtual memory, and the other is the child process virtual memory.
So now in the switch block, if child PID value is minus one, that means the fork has failed and we
returned from here.
In case of child PID equal to zero that means fork has returned zero.
And this is the child process.
So in the child process this case zero executes whereas parent process executes the default case.
If we observe here in the child process, the g data had value one, one, one and a I stack variable
had value 2 to 2 because the child is an exact duplicate of the parent process.
Now in child process, let's alter these variable values as shown in new values, and let's print these
values in both child and parent process.
Before compiling the code, if we observe, we have not altered these two variables in parent process.
Now let's compile the code.
Now let's execute it from output.
We can see in the parent process we have its PID as shown here.
And the value of g data and I stack data are 111 and 222 respectively.
And these are unaltered values.
Now in the child process we print its PID and print the value of these variables.
We can see that the values of these variable.
G data which is stored in data segment of child process and the variable I.
Stack which is stored in child process.
Stack segment is altered as per our code shown here.
By this we can conclude from the figure.
Initially there is only one parent process before.
Fork and after the fork.
There are two process in memory and both holds its own memory and the data value will be exactly same.
But if any process alters any values of these variables, it will be affected only to the process in
which it is altered and not in other process.
So from output, we have proven that virtual memory of parent and child is different As a note, there
is a concept called as c o w.
That is, copy on write.
In most of modern Linux system, when a fork system is created, there will be a child and parent process.
But here both these processes will point to the same virtual memory rather than having its own virtual
memory.
But when any process tries to change the value of variables stored in virtual memory, then a new page
frame of that page will be created.
This is called copy on write ether.
This is used to avoid the unnecessary copying of the complete virtual memory from parent to child.
Process.
This copy on write is added as a node for some extra information.
Purpose only.
Thank you for joining this session.