CEN301 – Operating System Problem Set 1
Q1) Draw the process hierarchy structurally of the sample codes given below without writing the
PIDs. #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void create_child() {
pid_t pid = fork();
if (pid < 0) {
perror("fork error");
exit(1); int main() {
} else if (pid == 0) { create_child(); // performs fork #1
exit(0);
} create_child2(); // performs forks #2 and #3
} wait(NULL);
void create_child2() {
pid_t pid = fork(); // fork #2 wait(NULL);
if (pid < 0) { return 0;
perror("fork error");
exit(1); }
} else if (pid == 0) {
create_child(); // performs fork #3
exit(0);
}
}
Process Hierarchy
// Created after fork #2
// Created after fork #1
// Created after fork #3
Q2) Draw the process hierarchy of the sample codes given below. Also write a possible output.
Here are some assumptions:
The pid of the root process is 10.
The output of the execlp("ls", "ls", "-l", NULL) system call is: "52 5.11.2024 main.c".
The output of the execlp("date", "date", NULL, NULL) system call is: "5.11.2024".
#include <stdio.h> int main() {
#include <stdlib.h> pid_t pid1, pid2;
pid1 = fork(); // fork #1
#include <unistd.h>
if (pid1 < 0) {
#include <sys/types.h> perror("Fork error");
#include <sys/wait.h> exit(EXIT_FAILURE);
void execute_command(const char *command, const char *arg) { } else if (pid1 == 0) {
if (execlp(command, command, arg, NULL) == -1) { printf("First Child Process - PID: %d, Parent PID: %d\n", getpid(), getppid()); // print #1
perror("Error executing command"); execute_command("ls", "-l"); // performs execlp #1 that takes the place of the child
exit(EXIT_FAILURE); process
}
} execute_command("date", NULL); // performs execlp #2 that takes the place of the root
} process
// The remaining commands do not work because excelp #2 replaces the root process
pid2 = fork();
if (pid2 < 0) {
perror("Fork error");
exit(EXIT_FAILURE);
} else if (pid2 == 0) {
printf("Second Child Process - PID: %d, Parent PID: %d\n", getpid(), getppid());
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
printf("Main Process - PID: %d is exiting.\n", getpid());
return 0;
}
Console Output Process Hierarchy
First Child Process - PID: 11, Parent PID: 10 // printed after print
#1 10
52 5.11.2024 main.c // printed after execlp #1
5.11.2024 // printed after execlp #2
11
Q3) Draw the process hierarchy of the sample codes given below. Suppose all fork calls are
successful. Just draw the hierarchy structurally without writing the PIDs. Also write a possible
output.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> fork(); // fork #1
#include <sys/wait.h> counter++;
int main() { fork(); // fork #2
int i = 0, counter = 0; counter++;
for(; i< 3; i++) fork(); // fork #3
{ counter++;
fork();
counter++;
}
printf("Final value of the counter : %d\n",counter); // Each process performs the print operation
return 0;
}
Console Output Process Hierarchy
Final value of the counter : 3
Final value of the counter : 3
Final value of the counter : 3
Final value of the counter : 3
// after // after fork #3
Final value of the counter : 3 // after fork #1
fork #2
Final value of the counter : 3
Final value of the counter : 3 // after fork #2 // after fork #3
Final value of the counter : 3 // after fork #3
// after fork #3
Q4) Draw the process hierarchy structurally of the sample codes given below without writing the
PIDs. Suppose all fork calls are successful.
void fun() void fun2()
{ {
// fork #1 pid_t pid = fork(); fork();
if(pid == 0) }
{ int main() {
// fork #2 fun2(); fun();
} return 0;
else }
{
fork(); // fork #3
// fork #4 fork();
}
}
Process Hierarchy
// after fork #1 // after fork #3 // after fork #4
// after fork #2 // after fork #4
Q5) Write a program to create the following process hierarchy. Suppose all fork calls are successful.
Do not check the return status of the fork calls.
// P1 // P2
// P3 // P4
// P5
Program Code
int main() {
pid_t pid;
pid = fork(); // to create p1
if(pid==0)
{
fork();// to create p3
fork();// to create p4 and p5
}
else
fork();// to create p2
printf("omer\n");
return 0;
}
Initial values a = 5, b= 4
Q6) Write a possible output of the sample codes given below. After a++ -> a = 6, b = 4
int main() {
// after fork #1
int a = 5, b = 4; a = 6, b = 4 a = 6, b = 4
a++; Root Process Child Process
pid_t pid = fork(); // fork #1
if(pid == 0)
a+= 2; a = 6, b= 4 a = 8, b= 4 // Only the child process performs.
b--; // Both the child and the root processes perform.
printf("a: %d, b: %d, a + b =%d\n",a,b, a + b); // after b--
return 0;
a = 6, b= 3 a = 8, b= 3
}
Console Output
a: 8, b: 3, a + b =11 // output of the child process
a: 6, b: 3, a + b =9 // output of the root process
Q7) Write a possible output of the sample codes given below.
Here are some assumptions:
The pid of the root process is 10.
All fork calls are successful.
10
int run(int pid)
{
printf("Pid :%d, getpid :%d\n",pid, getpid()); 11 // after fork #1 // after fork #2
12
fork();// fork #2
}
int main() { 13
// after fork #2
pid_t pid = fork(); // fork #1
run(pid);
printf("%d exited...\n",getpid()); // Each process performs the print operation
return 0;
}
Console Output
Pid :11, getpid :10
Printed after fork #1 in run function
Pid :0, getpid :11
10 exited...
11 exited...
12 exited...
13 exited...
Note: processes may terminate in a different order. So, the order of the outputs may change.
Q8) Write a program to create the following process hierarchy. Suppose all fork calls are successful.
Do not check the return status of the fork calls.
// P1 // P2 // P3
// P4
Program Code
int main() {
pid_t pid = fork(); // to create p1
if(pid > 0)
{
pid = fork();// to create p2
if(pid > 0)
{
int pid2 = fork();// to create p3
if(pid2 ==0)
fork();// to create p4
}
}
return 0;
}