OS Lecture 09 - 10
OS Lecture 09 - 10
Acknowledgement
Some slides and pictures are adapted from Lecture slides / Books of
• Dr. Syed Mansoor Sarwar.
• Muhammad Adeel Nisar
• Text Book - OS Concepts by Silberschatz, Galvin, and Gagne.
Process Creation
▪ Parent process create children processes, which, in
turn create other processes, forming a tree of
processes
▪ Generally, process identified and managed via a
process identifier (pid)
▪ Resource sharing options
• Parent and children share all resources
• Children share subset of parent’s resources
• Parent and child share no resources
▪ Execution options
• Parent and children execute concurrently
• Parent waits until children terminate
Process Creation (Cont.)
▪ Address space
• Child duplicate of parent
• Child has a program loaded into it
▪ UNIX examples
• fork() system call creates new process
• exec() system call used after a fork() to replace the process’
memory space with a new program
• Parent process calls wait()waiting for the child to terminate
A Tree of Processes in Linux
• init is parent of all Linux processes with PID or process ID of 1.
• It is the first process to start when a computer boots up and runs until the system shuts
down.
• init stands for initialization.
• In simple words the role of init is to create processes from script stored in the file
/etc/inittab which is a configuration file which is to be used by initialization system. It is
the last step of the kernel boot sequence.
• In Linux init is named as systemd.
Process Creation
7
Process Termination (cont…)
• A parent may terminate execution of one of its
children for a variety of reasons such as:
• Child has exceeded allocated resources (main
memory, execution time, etc.)
• Parent needs to create another child but has
reached its maximum children limit
• Task performed by the child is no longer required
• Parent exits
• OS does not allow child to continue if its parent
terminates
• Cascaded termination
8
Process Management in UNIX/Linux
➢ fork()
➢ exit()
➢ wait()
➢ exec()
9
System Call - fork()
▪ When the fork system call is executed, a new process is
created which consists of a copy of the address space of
the parent
SYNOPSIS
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
10
System Call - fork()
11
System Call - fork() ...
• On success: (Child process is created)
– The return code for fork is zero for the child process and the child
process ID is returned to the parent process
– Both processes continue execution at the instruction
after the fork call
12
Using fork() & exit() system call
• Parent forks PID: 597 Parent
1. //fork1.cpp
2. int main()
3. {
4. int i = 54, cpid = -1;
5. cpid = fork();
6. if (cpid == -1)
7. {
8. cout <<“\nFork failed\n”;
9. exit (1);
10. }
11. if (cpid == 0) //child code
12. cout <<“\n Hello I am child \n”;
13. else //parent code
14. cout <<(“\n Hello I am parent \n”;
15. }
DATA
i = 54
cpid = -1
13
Using fork() & exit() system call
PID: 597 Parent PID: 598 Child
1. //fork1.c 1. //fork1.c
2.int main() 2.int main()
3. { 3. {
4. int i = 54, cpid = -1; 4. int i = 54, cpid = -1;
5. cpid = fork(); 5. cpid = fork();
6.if (cpid == -1) 6.if (cpid == -1)
7. { 7. {
8. cout <<“\nFork failed\n”; 8. cout <<“\nFork failed\n”;
9. exit (1); 9. exit (1);
10. } 10. }
11. if (cpid == 0) //child code 11. if (cpid == 0) //child code
12. cout <<"\n Hello I am child \n”; 12. cout <<“\n Hello I am child \n”;
13. else //parent code 13. else //parent code
14. cout <<“\n Hello I am parent \n”; 14. cout <<“\n Hello I am parent \n”;
15. } 15. }
DATA DATA
i = 54 i = 54
cpid = 598 cpid = 0
• After fork parent and child are identical except for the return value of fork (and of
course the PIDs).
• Because data are different therefore program execution differs.
• They are free to execute on their own from now onwards, i.e. after a successful or
unsuccessful fork() system call both will start their execution from line#6.
14
Using fork() & exit() system call
PID: 597 Parent PID: 598 Child
1. //fork1.c 1. //fork1.c
2.int main() 2.int main()
3. { 3. {
4. int i = 54, cpid = -1; 4. int i = 54, cpid = -1;
5. cpid = fork(); 5. cpid = fork();
6.if (cpid == -1) 6.if (cpid == -1)
7. { 7. {
8. cout <<“\nFork failed\n”; 8. cout <<“\nFork failed\n”;
9. exit (1); 9. exit (1);
10. } 10. }
11. if (cpid == 0) //child code 11. if (cpid == 0) //child code
12. cout <<"\n Hello I am child \n”; 12. cout <<“\n Hello I am child \n”;
13. else //parent code 13. else //parent code
14. cout <<“\n Hello I am parent \n”; 14. cout <<“\n Hello I am parent \n”;
15. } 15. }
DATA DATA
i = 54 i = 54
cpid = 598 cpid = 0
• Process Tree
15
Using fork() & exit() system call
PID: 597 Parent PID: 598 Child
1. //fork1.c 1. //fork1.c
2.int main() 2.int main()
3. { 3. {
4. int i = 54, cpid = -1; 4. int i = 54, cpid = -1;
5. cpid = fork(); 5. cpid = fork();
6.if (cpid == -1) 6.if (cpid == -1)
7. { 7. {
8. cout <<“\nFork failed\n”; 8. cout <<“\nFork failed\n”;
9. exit (1); 9. exit (1);
10. } 10. }
11. if (cpid == 0) //child code 11. if (cpid == 0) //child code
12. cout <<“\n Hello I am child \n”; 12. cout <<“\n Hello I am child \n”;
13. else //parent code 13. else //parent code
14. cout << “\n Hello I am parent \n”; 14. cout << "\n Hello I am parent \n”;
15. } 15. }
DATA DATA
i – 54 i – 54
cpid = 598 cpid = 0
• When both will execute line 11, parent will now execute line 14 while child will
execute line 12.
16
Example 1 -fork() & exit()
//fork1.c
int main()
{
int cpid;
cpid = fork();
if (cpid == -1)
{
cout <<“\nFork failed\n”;
exit (1);
}
if (cpid == 0) //child code
cout <<“\n Hello I am child \n”;
else //parent code
cout <<“\n Hello I am parent \n”;
}
17
What will be the output of the code?
Output- 1 Output- 2
Hello I am child Hello I am parent
OR
Hello I am parent Hello I am child
• If child process executes first and then CPU executes the parent; we will get Output-1
•If parent process executes first, it terminates and the child process become Zombie, process init
takes over control and execute the child process as its own child and we get output similar to
Output-2
18
Example 2
Output: Output:
Before fork: Process id is 137 Before fork: Process id is 199
This is child process This is parent process
Process id is 138 and PPID is 137 Process id is 199 and PPID is 116
This is parent process Newly created process id or child pid is 200
Process id is 137 and PPID is 116 This is child process
Newly created process id or child pid is 138 Process id is 200 and PPID is 199
Example 3
Example 4
Example 5
fork() – Child inherits from the Parent
• The child process inherits the following attributes form the
parent:
– Environment
– Open File Descriptor table
– Signal handling settings
– Nice value
– Current working directory
– Root directory
– File mode creation mask (umask)
23
fork() – Child Differs from the Parent
• The child process differs from the parent process:
24
fork() – Reasons for Failure
• Maximum number of processes allowed to
execute under one user has exceeded
• Maximum number of processes allowed on the
system has exceeded
25
System Call - wait()
• The wait system call suspends the calling process until one
of its immediate children terminates, or until a child that is
being traced stops because it has hit an event of interest.
• wait returns prematurely if a signal is received. If all children
processes stopped or terminated prior to the call on wait,
return is immediate.
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *stat_loc);
26
System Call - wait()
• If the call is successful, the process ID of the terminating child
is returned
• If parent terminates, all its children are assigned process init
as new parent. Thus the children still have a parent to collect
their status and execution statistics
• Zombie process—a process that has terminated but whose
exit status has not yet been received by its parent process or
by init. (A process that has died but has yet not been reaped)
• Orphan process – a process that is still executing but whose
parent has died. They do not become zombie rather are
adopted by init process
27
Example - wait() system call
//fork2.cpp
int main()
{
int cpid, status;
cpid = fork();
if (cpid == -1)
{
cout << “\n Fork failed\n”;
exit (1);
}
if (cpid == 0){
cout<< “\n Hello I am child \n”;
exit(0);
}
else {
wait(&status);
cout << “\n Hello I am parent \n”;
}
28
Example - wait() system call
Output
I am a child process and my PID is : 3701
I am a parent process and my PID is: 3700
PID : 3701
My Child PID is: 3701 29
Example - Zombie Process
30
Example - Orphan Process
32
System Call exec()
• Typically the exec() system call is used after a fork() system
call by one of the two processes to replace the process
memory space with a new executable program.
• The new process image is constructed from an ordinary,
executable file.
• There can be no return from a successful exec() because
the calling process image is overlaid by the new process
image. Various Functions: execl, execlp, execle,
execv and execvp
#include <unistd.h>
int execlp(const char *file,const char *arg0,...,const char *argn,(char *)0);
• file is the path name of executable file which is going to override
the caller process
• arg0 is the name given to child process.
• arg1 may be the options passed to the process.
• Last argument is null pointer NULL
33
System Call exec()
Parent Parent
P1 P1
fork
exec
P2 ls ls
Child Child
34
Example - execlp() system call
//fork3.c
int main()
{
int cpid, status;
cpid = fork();
if (cpid == -1)
{
printf (“\nFork failed\n”);
exit (1);
}
if (cpid == 0){
execl(“/bin/ls”, “ls”, NULL);
//execl(“/bin/ls”, “ls”, “-la”, NULL);
//execl(“/bin/cal”, “cal”, NULL);
exit(0);
}
else {
wait(&status);
printf (“\n Hello I am parent \n”);
}
58
Example - execlp() system call
58
Example - execlp() system call
58