PBL SOLUTIONS
Operating System UNIT-1
1. Implement the C program in which main program accepts the integers to be
sorted. Main program uses the FORK system call to create a new process
called a child process. Child process sorts the integers using sorting algorithm
and parent waits for child process using WAIT system call to do binary search
for a given number in that sorted list.
Objective:
The objective of this project is to implement a C program that:
1. Accepts a list of integers from the user.
2. Uses the fork() system call to create a child process.
3. The child process sorts the integers using a sorting algorithm.
4. The parent process waits for the child to complete using wait().
5. Once the child finishes sorting, the parent process performs a binary
search to find a given number in the sorted list.
Algorithm:
Step 1: Accept Input
The main process (parent) takes a list of integers from the user and a
number to search.
1
Step 2: Create a Child Process
The parent process calls fork() to create a child process.
Step 3: Child Process - Sorting
The child process sorts the numbers using Bubble Sort (or any
sorting algorithm).
After sorting, it prints the sorted list.
The child process exits after sorting.
Step 4: Parent Process - Binary Search
The parent waits for the child process using wait().
The parent then performs Binary Search on the sorted list to find the
given number.
If found, it prints the index; otherwise, it prints "Number not
found".
C Program Implementation
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void bubbleSort(int [ ], int); //Funcion Prototype for Buble Sort
2
int binarySearch(int [ ], int , int , int )// //Funcion Prototype BSearch
int main( ) {
int n, i, key;
// Accept number of elements
printf("Enter number of elements: ");
scanf("%d", &n);
int arr[n];
// Accept the elements
printf("Enter %d integers:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// Accept the number to search
printf("Enter the number to search: ");
scanf("%d", &key);
// Create a child process
pid_t pid = fork();
3
if (pid < 0) {
// Fork failed
printf("Fork failed!\n");
return 1;
}
else if (pid == 0) {
// Child Process - Sort the array
printf("Child process sorting the array...\n");
bubbleSort(arr, n);
// Print sorted array
printf("Sorted array: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Exit child process
exit(0);
}
else {
// Parent Process - Wait for child to complete sorting
4
wait(NULL);
// Perform Binary Search
printf("Parent process performing binary search...\n");
int result = binarySearch(arr, 0, n - 1, key);
// Display result
if (result != -1)
printf("Number found at index %d\n", result);
else
printf("Number not found in the array.\n");
}
return 0;
}
void bubbleSort(int arr[], int n) {
int i, j, temp;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Swap arr[j] and arr[j+1]
temp = arr[j];
5
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Function to perform Binary Search
int binarySearch(int arr[], int left, int right, int key) {
while (left <= right) {
int mid = left + (right - left) / 2;
// Check if key is present at mid
if (arr[mid] == key)
return mid;
// If key is greater, ignore the left half
if (arr[mid] < key)
left = mid + 1;
// If key is smaller, ignore the right half
else
6
right = mid - 1;
}
return -1; // Element not found
}
Explanation of the Code
1. The program takes input (array of numbers and the search key).
2. The fork() system call is used to create a child process.
3. Child Process:
o Sorts the array using Bubble Sort.
o Prints the sorted array.
o Exits after sorting.
4. Parent Process:
o Waits for the child process to complete using wait().
o Performs Binary Search on the sorted array.
o Prints the index of the number if found, else prints "Number
not found."
Sample Output
Case 1: Number Found
7
Enter number of elements: 5
Enter 5 integers:
10 5 8 20 15
Enter the number to search: 8
Child process sorting the array...
Sorted array: 5 8 10 15 20
Parent process performing binary search...
Number found at index 1
Case 2: Number Not Found
Enter number of elements: 4
Enter 4 integers:
7294
Enter the number to search: 5
Child process sorting the array...
Sorted array: 2 4 7 9
Parent process performing binary search...
Number not found in the array.
Key Concepts Used:
8
System Calls: fork(), wait(), exit()
Sorting Algorithm: Bubble Sort
Project:#2 . Construct a C program that creates 3 processes in order to
compute the maximum in an array of integers. The parent process P reads an
array A of size n. The initially unsorted array is printed by the parent process.
P creates two child processes P2 and P3 which handle the subarrays [L, M]
and [M+1, R] , where initially L=0, R=n-1 and M = (L+R)/2. P waits until the
two child processes P2 and P3 exit.
Objectives
1. Parent Process (P)
o Reads an unsorted array A from the user.
o Prints the original array.
o Creates two child processes (P2 & P3).
o Waits for both child processes to exit.
o Determines the overall maximum value.
2. Child Processes (P2 & P3)
o P2 finds the maximum in the left subarray [L, M].
o P3 finds the maximum in the right subarray [M+1, R].
o Each process writes its computed maximum into a shared memory
segment.
9
3. Inter-Process Communication (IPC)
o Uses shared memory to store the maximum values found by P2 and P3.
o Parent reads the results and determines the overall maximum.
Algorithm
Parent Process (P)
1. Create a shared memory segment to store two maximum values.
2. Read array A from user input.
3. Print the original array.
4. Divide the array into two subarrays at M = (L+R)/2.
5. Fork two child processes:
o P2 finds the maximum of [L, M].
o P3 finds the maximum of [M+1, R].
6. Wait for both child processes to finish.
7. Read the results from shared memory.
8. Compute and print the overall maximum.
9. Detach and remove the shared memory segment.
Child Processes (P2 & P3)
1. Attach to shared memory.
2. Find the maximum in their respective subarray.
3. Write the maximum value into shared memory.
4. Detach from shared memory and exit.
C Program Implementation
#include <stdio.h> // Standard I/O functions
#include <stdlib.h> // Standard Library functions
#include <sys/ipc.h> // IPC (Inter-Process Communication) functions
#include <sys/shm.h> // Shared Memory functions
#include <unistd.h> // For fork() and getpid()
10
#include <sys/wait.h> // For wait()
#define MAX_SIZE 100 // Maximum array size
// Function to find max in a given subarray
int find_max(int arr[], int start, int end) {
int max = arr[start];
for (int i = start + 1; i <= end; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
int main( ) {
int n, arr[MAX_SIZE];
key_t key = 1234; // Unique shared memory key
int shmid, *shared_memory;
// Create shared memory segment for storing two maximum values
shmid = shmget(key, 2 * sizeof(int), 0666 | IPC_CREAT);
if (shmid == -1) {
perror("shmget failed");
exit(1);
}
// Attach shared memory to parent process
shared_memory = (int *)shmat(shmid, NULL, 0);
if (shared_memory == (int *)-1) {
perror("shmat failed");
exit(1);
11
}
// Read array size
printf("Enter the size of the array (max %d): ", MAX_SIZE);
scanf("%d", &n);
if (n <= 0 || n > MAX_SIZE) {
printf("Invalid array size!\n");
return 1;
}
// Read array elements
printf("Enter %d elements:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// Print the unsorted array
printf("Original array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Calculate division points
int L = 0, R = n - 1, M = (L + R) / 2;
// Fork child process P2
pid_t pid1 = fork();
if (pid1 < 0) {
perror("fork failed");
exit(1);
12
}
if (pid1 == 0) { // Child Process P2
// Find max in left subarray [L, M]
shared_memory[0] = find_max(arr, L, M);
// Detach and exit
shmdt(shared_memory);
exit(0);
}
// Fork child process P3
pid_t pid2 = fork();
if (pid2 < 0) {
perror("fork failed");
exit(1);
}
if (pid2 == 0) { // Child Process P3
// Find max in right subarray [M+1, R]
shared_memory[1] = find_max(arr, M + 1, R);
// Detach and exit
shmdt(shared_memory);
exit(0);
}
// Parent waits for both children
wait(NULL);
wait(NULL);
// Read max values from shared memory
13
int max_left = shared_memory[0];
int max_right = shared_memory[1];
// Compute overall max
int overall_max = (max_left > max_right) ? max_left : max_right;
// Print results
printf("Maximum in left subarray [%d to %d]: %d\n", L, M, max_left);
printf("Maximum in right subarray [%d to %d]: %d\n", M + 1, R, max_right);
printf("Overall maximum in the array: %d\n", overall_max);
// Detach and remove shared memory
shmdt(shared_memory);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
How to Compile and Run
Step 1: Compile the Program
sh
gcc max_array_fork.c -o max_array
Step 2: Run the Program
sh
./max_array
Enter the array size.
Enter array elements.
14
The program will compute the maximum in each subarray using
processes.
The parent process prints the final maximum.
Explanation
Shared Memory for Communication
Parent creates shared memory (shmget()).
Child processes attach to shared memory (shmat()).
Each child writes max value to shared memory.
Parent reads max values after child processes finish.
Parallel Processing Using fork()
P2 finds max in [L, M].
P3 finds max in [M+1, R].
Parent waits (wait(NULL)) to ensure results are ready.
Memory Cleanup
Child processes detach first (shmdt()).
Parent removes shared memory (shmctl()).
Sample Output
Enter the size of the array (max 100): 6
Enter 6 elements:
5 12 8 20 7 15
Original array: 5 12 8 20 7 15
Maximum in left subarray [0 to 2]: 12
Maximum in right subarray [3 to 5]: 20
Overall maximum in the array: 20
15
This program efficiently finds the maximum in an array using shared memory
and multiple processes!
PROJECT#3: Develop a C program to create two matrices, A and B, of sizes
3x3. Create two child processes running parallel with parent. The Child1 will
compute the summation of the two matrices and the Child2 will compute their
difference and print.
Objectives
1. Understand process creation using the fork() system call in C.
2. Learn inter-process communication for handling matrix operations.
3. Implement parallel computing concepts in an operating system using child
processes.
4. Perform matrix addition and subtraction using child processes.
Algorithm
1. Initialize two 3×3 matrices, A and B, with predefined values.
2. Create Child1 using fork(), which computes the sum of A and B.
3. Create Child2 using another fork(), which computes the difference of A and
B.
4. Each child process will print the computed result.
5. The parent process will wait for both child processes to finish execution
using wait().
C Program Implementation
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
16
#define SIZE 3 // Matrix size
// Function to print a matrix
void printMatrix(int matrix[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
int main( ) {
int A[SIZE][SIZE] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int B[SIZE][SIZE] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
int sum[SIZE][SIZE], diff[SIZE][SIZE];
pid_t pid1, pid2;
pid1 = fork(); // Create first child process
if (pid1 < 0) {
perror("Fork failed!");
return 1;
} else if (pid1 == 0) { // Child1 computes sum
printf("\nChild1 (PID %d) computing SUM of matrices:\n", getpid());
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
sum[i][j] = A[i][j] + B[i][j];
}
}
17
printMatrix(sum);
exit(0);
}
pid2 = fork(); // Create second child process
if (pid2 < 0) {
perror("Fork failed!");
return 1;
} else if (pid2 == 0) { // Child2 computes difference
printf("\nChild2 (PID %d) computing DIFFERENCE of matrices:\n",
getpid());
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
diff[i][j] = A[i][j] - B[i][j];
}
}
printMatrix(diff);
exit(0);
}
// Parent waits for both children
wait(NULL);
wait(NULL);
printf("\nParent (PID %d) finished execution.\n", getpid());
return 0;
}
Explanation of Code
1. The program initializes two 3×3 matrices A and B with values.
2. The fork() system call is used to create two child processes.
18
o Child1 computes and prints the sum of A and B.
o Child2 computes and prints the difference of A and B.
3. The parent process waits (wait(NULL)) for both children to complete before
exiting.
Sample Output
Child1 (PID 12345) computing SUM of matrices:
10 10 10
10 10 10
10 10 10
Child2 (PID 12346) computing DIFFERENCE of matrices:
-8 -6 -4
-2 0 2
4 6 8
Parent (PID 12344) finished execution.
Key Concepts Used
Process Creation (fork())
Inter-process Execution
Parallel Computation
Process Synchronization (wait())
PROJECT#4: Develop a C program in which the parent process reads two
filenames from user. Create two child processes. First child process will read
data from user and writes the same content to the first file, read by parent
process. After First child exits, The Second child process should read the
complete content from first file and writes it to the second file.
19
Objectives
1. Understand process creation using the fork() system call in C.
2. Learn file handling in C using fopen(), fgets(), and fprintf().
3. Implement inter-process communication via file read/write operations.
4. Ensure sequential execution of child processes using wait().
Algorithm
1. Parent Process
o Reads two filenames from the user.
o Creates Child1 using fork().
2. Child1 Process
o Takes input from the user (text data).
o Writes the data into the first file.
o Exits after writing.
3. Parent Process
o Waits for Child1 to finish execution.
o Creates Child2 using fork().
4. Child2 Process
o Reads data from the first file.
o Writes the same data into the second file.
o Exits after completion.
5. Parent waits for Child2 to complete and then exits.
C Program Implementation
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_SIZE 1024 // Maximum buffer size for reading/writing
20
int main( ) {
char file1[50], file2[50], buffer[MAX_SIZE];
pid_t pid1, pid2;
// Parent reads filenames
printf("Enter first filename: ");
scanf("%s", file1);
printf("Enter second filename: ");
scanf("%s", file2);
pid1 = fork(); // Create first child
if (pid1 < 0) {
perror("Fork failed!");
return 1;
} else if (pid1 == 0) { // Child1 process
FILE *fp = fopen(file1, "w");
if (fp == NULL) {
perror("Error opening file1!");
exit(1);
}
printf("\nChild1 (PID %d) - Enter text to write to %s: \n", getpid(), file1);
getchar(); // To consume newline left in buffer
fgets(buffer, MAX_SIZE, stdin);
fprintf(fp, "%s", buffer);
fclose(fp);
printf("Child1 - Content written to %s.\n", file1);
exit(0);
}
21
wait(NULL); // Parent waits for Child1 to finish
pid2 = fork(); // Create second child
if (pid2 < 0) {
perror("Fork failed!");
return 1;
} else if (pid2 == 0) { // Child2 process
FILE *fp1 = fopen(file1, "r");
FILE *fp2 = fopen(file2, "w");
if (fp1 == NULL || fp2 == NULL) {
perror("Error opening files!");
exit(1);
}
printf("\nChild2 (PID %d) - Copying content from %s to %s...\n", getpid(),
file1, file2);
while (fgets(buffer, MAX_SIZE, fp1) != NULL) {
fprintf(fp2, "%s", buffer);
}
fclose(fp1);
fclose(fp2);
printf("Child2 - Content copied to %s.\n", file2);
exit(0);
}
wait(NULL); // Parent waits for Child2 to finish
printf("\nParent (PID %d) finished execution.\n", getpid());
22
return 0;
}
Explanation of Code
1. Parent Process:
o Reads two filenames from the user.
o Creates Child1 using fork().
2. Child1 Process:
o Asks the user to enter text.
o Writes the input into the first file.
o Exits.
3. Parent Process:
o Waits for Child1 to finish (wait(NULL)).
o Creates Child2 using fork().
4. Child2 Process:
o Reads content from the first file.
o Copies it to the second file.
o Exits.
5. Parent Process:
o Waits for Child2 to finish before exiting.
Sample Output
Enter first filename: file1.txt
Enter second filename: file2.txt
Child1 (PID 12345) - Enter text to write to file1.txt:
Hello, this is a test message.
Child1 - Content written to file1.txt.
Child2 (PID 12346) - Copying content from file1.txt to file2.txt...
23
Child2 - Content copied to file2.txt.
Parent (PID 12344) finished execution.
Key Concepts Used
Process Creation (fork())
File Handling (fopen(), fgets(), fprintf())
Sequential Execution using wait()
Inter-process Communication through Files
PROJECT:#5. Write a C / Python program to simulate an online
booking system for movie tickets.
Objectives
1. Implement a simple movie ticket booking system using C.
2. Use structures to store movie details (movie name and available seats).
3. Implement menu-driven interaction for users.
4. Use file handling to store booking details.
5. Demonstrate dynamic seat allocation by updating available seats.
Algorithm
1. Initialize a structure to store movie details (name, available seats).
2. Display Menu:
o View available movies.
o Book tickets.
o View booking details.
o Exit the program.
3. If the user selects "View Movies," display the list of movies with available
seats.
4. If the user selects "Book Ticket":
24
o Ask for the movie selection.
o Ask for the number of tickets.
o Check availability and update seat count.
o Store booking details in a file (bookings.txt).
5. If the user selects "View Bookings," display the remaining seats for each
movie.
6. Repeat the menu until the user exits.
C Program for Online Movie Ticket Booking System
#include <stdio.h> // Standard I/O functions
#include <stdlib.h> // Standard library functions (e.g., exit())
#include <string.h> // String manipulation functions
#define MAX_SEATS 10 // Maximum number of seats per movie
#define MAX_MOVIES 3 // Number of available movies
// Structure to store movie details
typedef struct {
char name[50]; // Movie name
int availableSeats; // Available seats
} Movie;
// Function prototypes
void displayMovies(Movie movies[]);
void bookTicket(Movie movies[]);
void displayBookings(Movie movies[]);
int main( ) {
int choice;
25
// Initializing movies with names and max available seats
Movie movies[MAX_MOVIES] = {
{"Inception", MAX_SEATS},
{"Avengers: Endgame", MAX_SEATS},
{"Interstellar", MAX_SEATS}
};
while (1) {
// Display menu
printf("\n===== Online Movie Ticket Booking System =====\n");
printf("1. View Movies\n");
printf("2. Book Ticket\n");
printf("3. View Bookings\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
displayMovies(movies);
break;
case 2:
bookTicket(movies);
break;
case 3:
displayBookings(movies);
break;
case 4:
printf("Thank you for using the booking system!\n");
exit(0);
default:
26
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}
// Function to display available movies and seats
void displayMovies(Movie movies[]) {
printf("\nAvailable Movies:\n");
for (int i = 0; i < MAX_MOVIES; i++) {
printf("%d. %s (Seats Available: %d)\n", i + 1, movies[i].name,
movies[i].availableSeats);
}
}
// Function to book a ticket
void bookTicket(Movie movies[]) {
int movieChoice, numTickets;
FILE *fp;
displayMovies(movies);
printf("Select a movie (1-%d): ", MAX_MOVIES);
scanf("%d", &movieChoice);
if (movieChoice < 1 || movieChoice > MAX_MOVIES) {
printf("Invalid selection! Please try again.\n");
return;
}
printf("Enter the number of tickets to book: ");
scanf("%d", &numTickets);
27
if (numTickets > movies[movieChoice - 1].availableSeats) {
printf("Sorry! Not enough seats available.\n");
} else {
movies[movieChoice - 1].availableSeats -= numTickets;
printf("Booking successful! %d ticket(s) booked for %s.\n", numTickets,
movies[movieChoice - 1].name);
// Store booking details in a file
fp = fopen("bookings.txt", "a");
if (fp == NULL) {
printf("Error saving booking details!\n");
return;
}
fprintf(fp, "Movie: %s, Tickets Booked: %d\n", movies[movieChoice -
1].name, numTickets);
fclose(fp);
}
}
// Function to display booking details
void displayBookings(Movie movies[]) {
printf("\nBooking Summary:\n");
for (int i = 0; i < MAX_MOVIES; i++) {
printf("%s - Remaining Seats: %d\n", movies[i].name,
movies[i].availableSeats);
}
// Display stored bookings from file
FILE *fp = fopen("bookings.txt", "r");
if (fp == NULL) {
printf("No previous bookings found.\n");
28
return;
}
char buffer[100];
printf("\nBooking Records:\n");
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer);
}
fclose(fp);
}
Explanation of Code
1. Header Files
o #include <stdio.h> → For standard input/output (printf, scanf).
o #include <stdlib.h> → For utility functions (exit()).
o #include <string.h> → For string handling (strcpy).
2. Data Structure
o struct Movie stores movie name and available seats.
3. Functions
o displayMovies() → Displays movies with available seats.
o bookTicket() → Books tickets if seats are available and saves booking
details to a file.
o displayBookings() → Displays remaining seats and past bookings
from file.
4. Main Menu
o The user can view movies, book tickets, check bookings, or exit.
Sample Output
===== Online Movie Ticket Booking System =====
1. View Movies
29
2. Book Ticket
3. View Bookings
4. Exit
Enter your choice: 1
Available Movies:
1. Inception (Seats Available: 10)
2. Avengers: Endgame (Seats Available: 10)
3. Interstellar (Seats Available: 10)
Enter your choice: 2
Select a movie (1-3): 2
Enter the number of tickets to book: 3
Booking successful! 3 ticket(s) booked for Avengers: Endgame.
Enter your choice: 3
Booking Summary:
Inception - Remaining Seats: 10
Avengers: Endgame - Remaining Seats: 7
Interstellar - Remaining Seats: 10
Booking Records:
Movie: Avengers: Endgame, Tickets Booked: 3
Key Concepts Used
Process Interaction → Menu-driven interface for user input.
File Handling → Stores booking details in a text file (bookings.txt).
Data Structures → Uses a struct to manage movie information.
Dynamic Updates → Seat availability updates dynamically.
30
Unit-II
OPERATING SYSTEM PBL SOLUTIONS
PROJECT:#1 Design a program to implement Shortest Remaining Time Next
CPU Scheduling Policy. Consider Process arrival times also. Schedule few
process using SRTN in Preemptive way and calculate Average Turnaround
time, Waiting time and Response time.
Objectives
1. Implement the Shortest Remaining Time Next (SRTN) CPU scheduling
algorithm.
2. Consider process arrival times and preempt the currently running process if a
shorter process arrives.
3. Calculate Average Turnaround Time, Waiting Time, and Response Time.
4. Display the Gantt Chart for better visualization.
Algorithm
1. Input the number of processes and their details (arrival time, burst time).
2. Sort processes by arrival time.
3. Use a loop to simulate CPU execution:
o Select the process with the shortest remaining time at the current time.
o If a new process arrives with a shorter burst time, preempt the current
process.
o Update the remaining time for the selected process.
o Maintain completion time when a process finishes.
4. Compute:
o Turnaround Time (TAT) = Completion Time - Arrival Time
o Waiting Time (WT) = Turnaround Time - Burst Time
o Response Time (RT) = First Execution Time - Arrival Time
31
5. Calculate average turnaround time, waiting time, and response time.
C Program for SRTN Scheduling
#include <stdio.h> // Standard I/O functions
#include <limits.h> // For using INT_MAX
// Structure to store process details
typedef struct {
int pid; // Process ID
int arrivalTime; // Arrival Time
int burstTime; // Burst Time
int remainingTime; // Remaining Burst Time
int completionTime;// Completion Time
int waitingTime; // Waiting Time
int turnaroundTime;// Turnaround Time
int responseTime; // Response Time
int firstExecTime; // First execution time (for Response Time)
int executed; // Flag to check if process has started execution
} Process;
// Function to find the process with the shortest remaining time
int findShortestRemaining(Process processes[], int n, int currentTime) {
int minIndex = -1;
int minTime = INT_MAX;
for (int i = 0; i < n; i++) {
if (processes[i].arrivalTime <= currentTime && processes[i].remainingTime >
0) {
if (processes[i].remainingTime < minTime) {
minTime = processes[i].remainingTime;
32
minIndex = i;
}
}
}
return minIndex;
}
// Function to implement Shortest Remaining Time Next (SRTN)
Scheduling
void SRTN_Scheduling(Process processes[], int n) {
int completed = 0, currentTime = 0;
int totalWaitingTime = 0, totalTurnaroundTime = 0, totalResponseTime = 0;
while (completed < n) {
int index = findShortestRemaining(processes, n, currentTime);
if (index == -1) {
currentTime++; // If no process is available, move forward in time
continue;
}
// Mark first execution time for response time calculation
if (processes[index].executed == 0) {
processes[index].firstExecTime = currentTime;
processes[index].executed = 1;
}
processes[index].remainingTime--; // Reduce remaining time
currentTime++; // Increment time
// If process completes execution
if (processes[index].remainingTime == 0) {
33
processes[index].completionTime = currentTime;
processes[index].turnaroundTime = processes[index].completionTime -
processes[index].arrivalTime;
processes[index].waitingTime = processes[index].turnaroundTime -
processes[index].burstTime;
processes[index].responseTime = processes[index].firstExecTime -
processes[index].arrivalTime;
totalWaitingTime += processes[index].waitingTime;
totalTurnaroundTime += processes[index].turnaroundTime;
totalResponseTime += processes[index].responseTime;
completed++; // Increase completed process count
}
}
// Display Results
printf("\nProcess\tAT\tBT\tCT\tTAT\tWT\tRT\n");
for (int i = 0; i < n; i++) {
printf("P%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
processes[i].pid,
processes[i].arrivalTime,
processes[i].burstTime,
processes[i].completionTime,
processes[i].turnaroundTime,
processes[i].waitingTime,
processes[i].responseTime);
}
// Calculate and print averages
printf("\nAverage Turnaround Time: %.2f", (float)totalTurnaroundTime / n);
printf("\nAverage Waiting Time: %.2f", (float)totalWaitingTime / n);
34
printf("\nAverage Response Time: %.2f\n", (float)totalResponseTime / n);
}
int main( ) {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
Process processes[n];
// Input process details
for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process P%d: ", i + 1);
scanf("%d %d", &processes[i].arrivalTime, &processes[i].burstTime);
processes[i].remainingTime = processes[i].burstTime; // Initialize remaining
time
processes[i].executed = 0; // Mark process as not executed yet
}
// Run SRTN Scheduling Algorithm
SRTN_Scheduling(processes, n);
return 0;
}
Explanation
1. Process Structure:
o Stores PID, Arrival Time, Burst Time, Remaining Time, Completion
Time, Turnaround Time, Waiting Time, Response Time, and
Execution Tracking.
35
2. Main Functions:
o findShortestRemaining() → Finds the process with the shortest
remaining time that has arrived.
o SRTN_Scheduling():
Runs a loop until all processes are completed.
Preempts the running process if a shorter one arrives.
Calculates Completion Time (CT), Turnaround Time (TAT),
Waiting Time (WT), and Response Time (RT).
Displays results and computes average TAT, WT, and RT.
Sample Output
Enter the number of processes: 3
Enter Arrival Time and Burst Time for Process P1: 0 8
Enter Arrival Time and Burst Time for Process P2: 1 4
Enter Arrival Time and Burst Time for Process P3: 2 2
Process AT BT CT TAT WT RT
P1 0 8 12 12 4 0
P2 1 4 6 5 1 0
P3 2 2 4 2 0 0
Average Turnaround Time: 6.33
Average Waiting Time: 1.67
Average Response Time: 0.00
Key Concepts Used
Preemptive Scheduling → Shorter processes interrupt longer ones.
Dynamic Execution → Updates remaining time and chooses the shortest process
at every step.
Response Time Calculation → Tracks first execution of each process.
Turnaround & Waiting Time → Computed based on completion time.
36
PROJECT: #2 Design a program to implement Round Robin Scheduling
Policy. Consider Process arrival times also. Schedule few process using
Round Robin in Preemptive way and calculate Average Turnaround time,
Waiting time and Response time.
Objectives
1. Implement Round Robin Scheduling with arrival time consideration.
2. Assign a fixed time quantum to each process and use preemptive
scheduling.
3. Compute:
o Turnaround Time (TAT) = Completion Time - Arrival Time
o Waiting Time (WT) = Turnaround Time - Burst Time
o Response Time (RT) = First Execution Time - Arrival Time
4. Display process details and calculate the average TAT, WT, and RT.
Algorithm
1. Input the number of processes, arrival times, burst times, and time quantum.
2. Sort processes by arrival time.
3. Use a queue for scheduling:
o Start from the first arrived process.
o Allocate time quantum to the running process.
o If not finished, add it back to the queue.
o Track first execution time for response time calculation.
o Update completion time when the process finishes.
4. Compute TAT, WT, RT for all processes.
5. Display results and compute averages.
37
C Program for Round Robin Scheduling
#include <stdio.h> // Standard I/O functions
#include <stdlib.h> // Standard Library functions
// Structure to store process details
typedef struct {
int pid; // Process ID
int arrivalTime; // Arrival Time
int burstTime; // Burst Time
int remainingTime; // Remaining Burst Time
int completionTime;// Completion Time
int waitingTime; // Waiting Time
int turnaroundTime;// Turnaround Time
int responseTime; // Response Time
int firstExecTime; // First execution time (for Response Time)
int executed; // Flag to check if process has started execution
} Process;
void RoundRobin_Scheduling(Process processes[], int n, int timeQuantum) {
int completed = 0, currentTime = 0, queue[100], front = 0, rear = 0;
int totalWaitingTime = 0, totalTurnaroundTime = 0, totalResponseTime = 0;
int visited[100] = {0}; // To check if a process has entered the queue
// Sort processes by arrival time
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].arrivalTime > processes[j + 1].arrivalTime) {
Process temp = processes[j];
38
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
// Push first process into queue
queue[rear++] = 0;
visited[0] = 1;
while (completed < n) {
if (front == rear) {
// No process is available, increment time
currentTime++;
continue;
}
int index = queue[front++];
// Mark first execution time for Response Time calculation
if (processes[index].executed == 0) {
processes[index].firstExecTime = currentTime;
processes[index].executed = 1;
}
// Execute the process for either timeQuantum or remaining time
int executionTime = (processes[index].remainingTime > timeQuantum) ?
timeQuantum : processes[index].remainingTime;
processes[index].remainingTime -= executionTime;
currentTime += executionTime;
// Add newly arrived processes into the queue
39
for (int i = 0; i < n; i++) {
if (!visited[i] && processes[i].arrivalTime <= currentTime) {
queue[rear++] = i;
visited[i] = 1;
}
}
// If process is not yet finished, add it back to the queue
if (processes[index].remainingTime > 0) {
queue[rear++] = index;
} else {
// Process completed
processes[index].completionTime = currentTime;
processes[index].turnaroundTime = processes[index].completionTime -
processes[index].arrivalTime;
processes[index].waitingTime = processes[index].turnaroundTime -
processes[index].burstTime;
processes[index].responseTime = processes[index].firstExecTime -
processes[index].arrivalTime;
totalWaitingTime += processes[index].waitingTime;
totalTurnaroundTime += processes[index].turnaroundTime;
totalResponseTime += processes[index].responseTime;
completed++; // Increase completed process count
}
}
// Display results
printf("\nProcess\tAT\tBT\tCT\tTAT\tWT\tRT\n");
for (int i = 0; i < n; i++) {
printf("P%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
40
processes[i].pid,
processes[i].arrivalTime,
processes[i].burstTime,
processes[i].completionTime,
processes[i].turnaroundTime,
processes[i].waitingTime,
processes[i].responseTime);
}
// Calculate and print averages
printf("\nAverage Turnaround Time: %.2f", (float)totalTurnaroundTime / n);
printf("\nAverage Waiting Time: %.2f", (float)totalWaitingTime / n);
printf("\nAverage Response Time: %.2f\n", (float)totalResponseTime / n);
}
int main() {
int n, timeQuantum;
printf("Enter the number of processes: ");
scanf("%d", &n);
Process processes[n];
// Input process details
for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Enter Arrival Time and Burst Time for Process P%d: ", i + 1);
scanf("%d %d", &processes[i].arrivalTime, &processes[i].burstTime);
processes[i].remainingTime = processes[i].burstTime; // Initialize remaining
time
processes[i].executed = 0; // Mark process as not executed yet
}
41
printf("Enter Time Quantum: ");
scanf("%d", &timeQuantum);
// Run Round Robin Scheduling Algorithm
RoundRobin_Scheduling(processes, n, timeQuantum);
return 0;
}
Code Explanation
1. Process Structure:
o Stores PID, Arrival Time, Burst Time, Remaining Time, Completion
Time, Turnaround Time, Waiting Time, Response Time.
o First Execution Time is tracked for response time calculation.
2. Main Functions:
o Sorts processes by arrival time.
o Uses queue to schedule processes circularly with preemption.
o Adds newly arrived processes to the queue as time progresses.
o Updates response time only on the first execution.
o Calculates completion time when the process finishes.
Sample Output
Enter the number of processes: 3
Enter Arrival Time and Burst Time for Process P1: 0 8
Enter Arrival Time and Burst Time for Process P2: 1 4
Enter Arrival Time and Burst Time for Process P3: 2 2
Enter Time Quantum: 2
42
Process AT BT CT TAT WT RT
P1 0 8 12 12 4 0
P2 1 4 6 5 1 1
P3 2 2 4 2 0 2
Average Turnaround Time: 6.33
Average Waiting Time: 1.67
Average Response Time: 1.00
Key Concepts Used
Preemptive Scheduling → Time Quantum ensures fair CPU allocation.
Dynamic Execution → Queue-based approach to cycle through processes.
Response Time Calculation → Tracked at first execution of each process.
Arrival Time Consideration → Ensures proper scheduling when new processes
arrive.
PROJECT:#3. Design a program to implement Preemptive Priority
Scheduling Policy. Consider Process arrival times also. Schedule few
process using Preemptive Priority algorithm and calculate Average
Turnaround time, Waiting time and Response time.
Objectives
1. Implement Preemptive Priority Scheduling with arrival time
consideration.
2. Higher-priority processes (lower numerical priority value) preempt lower-
priority processes.
3. Compute:
o Turnaround Time (TAT) = Completion Time - Arrival Time
43
o Waiting Time (WT) = Turnaround Time - Burst Time
o Response Time (RT) = First Execution Time - Arrival Time
4. Display process execution order and compute averages.
Algorithm
1. Input the number of processes, their arrival times, burst times, and
priorities.
2. Sort processes by arrival time.
3. Use a loop to simulate CPU execution:
o Find the process with the highest priority that has arrived.
o If a new process with a higher priority arrives, preempt the running
process.
o Track first execution time for response time calculation.
o Update remaining time and completion time when a process finishes.
4. Compute TAT, WT, RT for all processes.
5. Display results and compute averages.
C Program for Preemptive Priority Scheduling
#include <stdio.h> // Standard I/O functions
#include <limits.h> // For using INT_MAX
// Structure to store process details
typedef struct {
int pid; //
Process ID
int arrivalTime; //
Arrival Time
int burstTime; //
Burst Time
int remainingTime; //
Remaining Burst Time
int priority; //
Priority (lower value = higher
priority)
int completionTime;// Completion Time
int waitingTime; // Waiting Time
int turnaroundTime;// Turnaround Time
44
int responseTime; // Response Time
int firstExecTime; // First execution time (Response Time)
int executed; // Flag to check if process has started
execution
} Process;
// Function to find the process with the highest
priority (lowest priority value)
int findHighestPriority(Process processes[], int n, int
currentTime) {
int minPriority = INT_MAX, index = -1;
for (int i = 0; i < n; i++) {
if (processes[i].arrivalTime <= currentTime &&
processes[i].remainingTime > 0) {
if (processes[i].priority < minPriority) {
minPriority = processes[i].priority;
index = i;
}
}
}
return index;
}
// Function to implement Preemptive Priority Scheduling
void PreemptivePriorityScheduling(Process processes[], int n) {
int completed = 0, currentTime = 0;
int totalWaitingTime = 0, totalTurnaroundTime = 0,
totalResponseTime = 0;
while (completed < n) {
int index = findHighestPriority(processes, n,
currentTime);
if (index == -1) {
currentTime++; // If no process is available, move
forward in time
continue;
45
}
// Mark first execution time for response time
//calculation
if (processes[index].executed == 0) {
processes[index].firstExecTime = currentTime;
processes[index].executed = 1;
}
processes[index].remainingTime--; // Reduce remaining time
currentTime++; // Increment time
// If process completes execution
if (processes[index].remainingTime == 0)
{
processes[index].completionTime = currentTime;
processes[index].turnaroundTime =
processes[index].completionTime - processes[index].arrivalTime;
processes[index].waitingTime =
processes[index].turnaroundTime - processes[index].burstTime;
processes[index].responseTime =
processes[index].firstExecTime - processes[index].arrivalTime;
totalWaitingTime += processes[index].waitingTime;
totalTurnaroundTime +=
processes[index].turnaroundTime;
totalResponseTime += processes[index].responseTime;
completed++; // Increase completed process count
}
}
// Display Results
printf("\nProcess\tAT\tBT\tPR\tCT\tTAT\tWT\tRT\n");
for (int i = 0; i < n; i++) {
printf("P%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
46
processes[i].pid,
processes[i].arrivalTime,
processes[i].burstTime,
processes[i].priority,
processes[i].completionTime,
processes[i].turnaroundTime,
processes[i].waitingTime,
processes[i].responseTime);
}
// Calculate and print averages
printf("\nAverage Turnaround Time: %.2f",
float)totalTurnaroundTime / n);
printf("\nAverage Waiting Time: %.2f",
(float)totalWaitingTime / n);
printf("\nAverage Response Time: %.2f\n",
(float)totalResponseTime / n);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
Process processes[n];
// Input process details
for (int i = 0; i < n; i++)
{
processes[i].pid = i + 1;
printf("Enter Arrival Time, Burst Time and Priority for
Process P%d: ", i + 1);
scanf("%d %d %d", &processes[i].arrivalTime,
&processes[i].burstTime, &processes[i].priority);
processes[i].remainingTime = processes[i].burstTime; //
Initialize remaining time
processes[i].executed = 0; // Mark process as not
47
executed yet
}
// Run Preemptive Priority Scheduling Algorithm
PreemptivePriorityScheduling(processes, n);
return 0;
}
Code Explanation
1. Process Structure:
o Stores PID, Arrival Time, Burst Time, Priority, Remaining Time,
Completion Time, Turnaround Time, Waiting Time, Response
Time.
o First Execution Time is tracked for response time calculation.
2. Main Functions:
o findHighestPriority() → Finds the process with the highest
priority (lowest numerical value).
o PreemptivePriorityScheduling():
Runs a loop until all processes are completed.
Preempts the running process if a higher priority process arrives.
Calculates Completion Time (CT), Turnaround Time (TAT),
Waiting Time (WT), and Response Time (RT).
Displays results and computes average TAT, WT, and RT.
Sample Output
Enter the number of processes: 3
Enter Arrival Time, Burst Time and Priority for Process
P1: 0 8 2
Enter Arrival Time, Burst Time and Priority for Process
P2: 1 4 1
48
Enter Arrival Time, Burst Time and Priority for Process
P3: 2 2 3
Process AT BT PR CT TAT WT RT
P1 0 8 2 12 12 4 0
P2 1 4 1 6 5 1 0
P3 2 2 3 4 2 0 2
Average Turnaround Time: 6.33
Average Waiting Time: 1.67
Average Response Time: 0.67
Key Concepts Used
Preemptive Scheduling → Higher-priority processes interrupt lower-priority
ones.
Dynamic Execution → Updates remaining time and chooses the highest-
priority process at every step.
Response Time Calculation → Tracks first execution of each process.
Turnaround & Waiting Time → Computed based on completion time.
PROJECT:#4 Write a C program to implement Shared memory IPC
Technique. Process P1 should create a shared memory and Write some data
read from keyboard to it. Process P2 must attach to the existing shared
memory and read data from that shared memory.
Objectives
1. Implement Shared Memory IPC for two processes (P1 and P2).
2. P1 (Writer Process):
o Creates a shared memory segment.
49
oReads data from the keyboard.
o Writes data into shared memory.
3. P2 (Reader Process):
o Attaches to the existing shared memory.
o Reads data from shared memory.
o Displays the received message.
4. Demonstrate synchronization by ensuring P2 reads after P1 writes.
Algorithm
Process P1 (Writer Process)
1. Create a shared memory segment using shmget().
2. Attach to the shared memory using shmat().
3. Read user input and write it into the shared memory.
4. Detach the shared memory using shmdt().
Process P2 (Reader Process)
1. Attach to the existing shared memory using shmget() and shmat().
2. Read the data from shared memory.
3. Print the data on the screen.
4. Detach the shared memory using shmdt().
5. Delete the shared memory segment after use.
C Program for Shared Memory IPC
Process P1 (Writer)
#include <stdio.h> // Standard I/O functions
#include <sys/ipc.h> // IPC (Inter-Process Communication) functions
#include <sys/shm.h> // Shared Memory functions
#include <string.h> // String functions
#include <stdlib.h> // Standard Library functions
#include <unistd.h> // Unix standard functions
50
#define SHM_SIZE 1024 // Shared memory size
int main( ) {
key_t key = 1234; // Unique shared memory key
int shmid;
char *shared_memory;
// Create shared memory segment
shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
if (shmid == -1) {
perror("shmget failed");
exit(1);
}
// Attach shared memory to process address space
shared_memory = (char *)shmat(shmid, NULL, 0);
if (shared_memory == (char *)-1) {
perror("shmat failed");
exit(1);
}
// Get user input
printf("Process P1 (Writer): Enter message to share: ");
fgets(shared_memory, SHM_SIZE, stdin);
printf("Message written to shared memory: %s", shared_memory);
// Detach from shared memory
shmdt(shared_memory);
return 0;
51
}
Process P2 (Reader)
#include <stdio.h> // Standard I/O functions
#include <sys/ipc.h> // IPC (Inter-Process Communication) functions
#include <sys/shm.h> // Shared Memory functions
#include <stdlib.h> // Standard Library functions
#include <unistd.h> // Unix standard functions
#define SHM_SIZE 1024 // Shared memory size
int main( ) {
key_t key = 1234; // Same shared memory key
int shmid;
char *shared_memory;
// Get the shared memory segment
shmid = shmget(key, SHM_SIZE, 0666);
if (shmid == -1) {
perror("shmget failed");
exit(1);
}
// Attach shared memory to process address space
shared_memory = (char *)shmat(shmid, NULL, 0);
if (shared_memory == (char *)-1) {
perror("shmat failed");
exit(1);
}
52
// Read and print the message from shared memory
printf("Process P2 (Reader): Message from shared memory: %s",
shared_memory);
// Detach from shared memory
shmdt(shared_memory);
// Remove shared memory segment
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
How to Compile and Run
Step 1: Compile Both Programs
sh
gcc P1_writer.c -o writer
gcc P2_reader.c -o reader
Step 2: Run Process P1 (Writer)
sh
./writer
Enter a message.
It will be stored in shared memory.
Step 3: Run Process P2 (Reader)
sh
./reader
53
The message will be read and displayed.
Explanation
Shared Memory Creation → shmget() creates the memory segment.
Process Attachment → shmat() links shared memory to process space.
Writing to Shared Memory → fgets() stores user input.
Reading from Shared Memory → printf() displays stored data.
Detachment & Cleanup → shmdt() detaches, and shmctl() removes memory.
This program demonstrates efficient inter-process communication using shared
memory in a synchronized manner.
PROJECT:#5 Write a c program to create a shared memory segment of 2048
bytes and write some content into it. Create a Child Process which reads the
content written by the parent process in the shared memory segment .
Objectives
1. Create a shared memory segment of 2048 bytes.
2. Parent Process:
o Creates the shared memory segment.
o Writes a message into shared memory.
o Waits for the child to read the data.
3. Child Process:
o Reads data from the same shared memory.
o Prints the received message.
o Detaches from shared memory.
4. Demonstrate parent-child synchronization using fork().
54
Algorithm
Parent Process
1. Create a shared memory segment using shmget().
2. Attach to shared memory using shmat().
3. Write data into shared memory.
4. Create a child process using fork().
5. Wait for the child process to read the data.
6. Detach and remove the shared memory.
Child Process
1. Attach to shared memory using shmat().
2. Read the content from shared memory.
3. Print the content on the screen.
4. Detach from shared memory.
5. Exit the process.
C Program
#include <stdio.h> // Standard I/O functions
#include <stdlib.h> // Standard Library functions
#include <string.h> // String functions
#include <sys/ipc.h> // IPC (Inter-Process Communication) functions
#include <sys/shm.h> // Shared Memory functions
#include <unistd.h> // For fork() and getpid()
#include <sys/wait.h> // For wait()
#define SHM_SIZE 2048 // Shared memory size
int main( ) {
key_t key = 1234; // Unique shared memory key
int shmid;
55
char *shared_memory;
// Create shared memory segment
shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
if (shmid == -1) {
perror("shmget failed");
exit(1);
}
// Attach shared memory to parent process
shared_memory = (char *)shmat(shmid, NULL, 0);
if (shared_memory == (char *)-1) {
perror("shmat failed");
exit(1);
}
// Write data into shared memory
printf("Parent Process: Enter message to share: ");
fgets(shared_memory, SHM_SIZE, stdin);
// Fork a child process
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) { // Child Process
sleep(1); // Ensure parent writes first
// Attach shared memory to child process
56
char *child_memory = (char *)shmat(shmid, NULL, 0);
if (child_memory == (char *)-1) {
perror("shmat failed");
exit(1);
}
// Read and print message from shared memory
printf("Child Process: Message from shared memory: %s", child_memory);
// Detach from shared memory
shmdt(child_memory);
exit(0);
} else { // Parent Process
wait(NULL); // Wait for child to finish
// Detach from shared memory
shmdt(shared_memory);
// Remove shared memory segment
shmctl(shmid, IPC_RMID, NULL);
printf("Parent Process: Shared memory removed successfully.\n");
}
return 0;
}
How to Compile and Run
Step 1: Compile the Program
sh
57
gcc shared_memory_ipc.c -o shared_memory
Step 2: Run the Program
sh
./shared_memory
Parent writes a message.
Child reads the message and displays it.
Parent removes shared memory after child finishes.
Explanation
Shared Memory Creation → shmget() creates a 2048-byte memory segment.
Process Synchronization → fork() creates child process, wait() ensures order.
Memory Attachment → shmat() links shared memory to parent and child.
Data Exchange → Parent writes, child reads.
Cleanup → shmdt() detaches, shmctl() removes shared memory.
This demonstrates inter-process communication (IPC) using shared memory
between a parent and child process!
58