AIM: To Write C Program to implement CPU and Scheduling for First Come First
Serve Process Scheduling
ALGORITHM:
STEP 1: Start the Program
STEP 2: Get the Number of the Processes and their burst time
STEP 3: Initialize the waiting time for process 1 and 0
STEP 4: Processes for( i=2; i<=n; i++), Wt . p[i]=p[i-1]+ bt. P[i-1].
STEP 5: The waiting time of all the process is summed then average value time
is Calculated.
STEP 6: The waiting time of each process and average times are displayed
STEP 7: Stop the Program.
PROGRAM:
#include<stdio.h>
int main()
{
int n,bt[20],wt[20],tat[20],avwt=0,avtat=0,i,j;
printf("Enter total number of processes(maximum 20):");
scanf("%d",&n);
printf("\nEnter Process Burs time\n");
for(i=0;i<n;i++)
{
printf("P[%d]:",i+1);
scanf("%d",&bt[i]);
}
wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
}
printf("\nProcess\t\tBurst Time\tWaiting Time\tTurnaround Time");
for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i];
avwt+=wt[i];
avtat+=tat[i];
printf("\nP[%d]\t\t%d\t\t%d\t\t%d",i+1,bt[i],wt[i],tat[i]);
}
avwt/i;
avtat/i;
printf("\n\nAverage Waiting Time:%d",avwt);
printf("\nAverage Turnaround Time:
%d",avtat);
return 0;
}
OUTPUT:
RESULT
Thus, the program has been Verified and executed successfully
AIM:
To write a program to implement CPU scheduling algorithm for Shortest Job
First Scheduling.
ALGORITHM:
STEP 1: Start the program. Get the number of processes and their burst time.
STEP 2: Initialize the waiting time for process 1 as 0.
STEP 3: The processes are stored according to their burst time.
STEP 4: The waiting time for the processes are calculated as follows:
for(i=2;i<=n;i++).p[i]=p[i=1]+bt.p[i-1].
STEP 5: The waiting time of all the processes summed and then the average time
calculated.
STEP 6: The waiting time of each process and average time are displayed.
STEP 7: Stop the process
PROGRAM:
#include<conio.h>
#include<stdio.h>
void main()
{
int i, j, n, process[10], total=0, wtime[10], ptime[10], temp, ptemp;
float avg=0;
clrscr();
printf("\nEnter number of Processes:");
scanf("%d", &n);
for(i=0;i<n;i++)
{
printf("\nEnter Process %d ID:",i+1);
scanf("%d", &process[i]); printf("\
nEnter Process %d Time:",i+1);
scanf("%d",&ptime[i]);
}
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(ptime[i]>ptime[j])
temp = ptime[i]; ptime[i] =
ptime[j];p
time[j] =
temp;
ptemp=pr
ocess[i];
process[i]
=
process[j]
;
process[j]
= ptemp;
wtime[
0]=0;
for(i=1
;i<n;i+
+)
wtime[i]=wtime[i-1]+ptime[i-1];total=total+wtime[i];
}
avg=(float)total/n;
printf("\nP_ID\t P_TIME\t
W_TIME\n"); for(i=0;i<n;i++)
printf("%d\t %d\t %d\n",process[i],ptime[i],wtime[i]);
printf("\nTotal Waiting Time: %d \nAverage Waiting Time:
%f", total, avg); getch();
}
Ex.No.4:IMPLEMENT ROUND ROBIN AND PRIORITY SCHEDULING
ALGORITHM IN CPU SCHEDULING
Aim:
To implement the Round Robin and Priority Scheduling algorithms in CPU scheduling . The
aim is to understand how processes are scheduled based on their priority or in a cyclic manner,
and how the CPU allocates time for each process.
ALGORITHM
Round Robin Scheduling
Step 1: Assign a fixed time quantum to each process.
Step 2:Execute each process for one time quantum in a cyclic manner.
Step 3:If a process doesn't complete within the quantum, it is preempted and re-added to
the queue.
Step 4:Repeat this until all processes are completed.
Priority Scheduling
Step 1:Each process has a priority.
Step 2:The CPU always executes the process with the highest priority (lowest numerical
value).
Step 3:In case of equal priority, processes are executed based on their arrival time or
other criteria (e.g., FCFS).
PROGRAM
#include <stdio.h>
#include <unistd.h>
void roundRobin(int processes[], int n, int burst_time[], int quantum) {
int remaining_time[n], i;
for(i = 0; i < n; i++) remaining_time[i] = burst_time[i];
while(1) {
int done = 1;
for(i = 0; i < n; i++) {
if(remaining_time[i] > 0) {
done = 0;
if(remaining_time[i] > quantum) {
remaining_time[i] -= quantum;
printf("Process %d executed for %d units.\n", processes[i], quantum);
} else {
printf("Process %d executed for %d units.\n", processes[i], remaining_time[i]);
remaining_time[i] = 0;
}
}
}
if(done) break;
}
}
int main() {
int processes[] = {1, 2, 3};
int burst_time[] = {10, 5, 8};
roundRobin(processes, 3, burst_time, 4);
return 0;
}
Output (Round Robin):
Process 1 executed for 4 units.
Process 2 executed for 4 units.
Process 3 executed for 4 units.
Process 1 executed for 4 units.
Process 2 executed for 1 units.
Process 3 executed for 4 units.
Process 1 executed for 2 units.
Priority Scheduling program
#include <stdio.h>
void priorityScheduling(int processes[], int n, int burst_time[], int priority[]) {
int i, j, temp;
for(i = 0; i < n; i++) {
for(j = i + 1; j < n; j++) {
if(priority[i] > priority[j]) {
temp = priority[i]; priority[i] = priority[j]; priority[j] = temp;
temp = processes[i]; processes[i] = processes[j]; processes[j] = temp;
temp = burst_time[i]; burst_time[i] = burst_time[j]; burst_time[j] = temp;
}
}
}
for(i = 0; i < n; i++) printf("Process %d with priority %d executed.\n", processes[i], priority[i]);
}
int main() {
int processes[] = {1, 2, 3};
int burst_time[] = {10, 5, 8};
int priority[] = {3, 1, 2};
priorityScheduling(processes, 3, burst_time, priority);
return 0;
}
Output (Priority Scheduling):
Process 2 with priority 1 executed.
Process 3 with priority 2 executed.
Process 1 with priority 3 executed.
Ex.No.5:Implement reader/writer problems using semaphore
Aim of the Reader-Writer Problem:
The aim of the Reader-Writer problem is to manage concurrent access to a shared resource
where:
Readers can read the resource simultaneously.
Writers need exclusive access to the resource (no readers or other writers should access
the resource while writing).
Algorithm for Reader-Writer Problem (Using Semaphores):
1. Reader Process:
Step 1:Lock the mutex to update the reader count.
Step 2:If it's the first reader (i.e., readCount == 1), acquire the writeLock to block
any writers.
Step 3:Unlock the mutex after updating the reader count.
Step 4:Perform the reading task.
Step 5:Lock the mutex again to update the reader count.
Step 6:If it's the last reader (readCount == 0), release the writeLock to allow
writers to write.
Step 7:Unlock the mutex.
2. Writer Process:
Step 8:Acquire the writeLock to get exclusive access to the shared resource.
Step 9:Perform the writing task.
Step 10:Release the writeLock.
PROGRAM
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
sem_t mutex, writeLock;
int readCount = 0;
void *reader(void *param) {
sem_wait(&mutex);
readCount++;
if (readCount == 1) sem_wait(&writeLock); // Block writers
sem_post(&mutex);
// Reading code (simulated)
printf("Reading\n");
sem_wait(&mutex);
readCount--;
if (readCount == 0) sem_post(&writeLock); // Allow writers
sem_post(&mutex);
}
void *writer(void *param) {
sem_wait(&writeLock); // Exclusive access
// Writing code (simulated)
printf("Writing\n");
sem_post(&writeLock);
}
int main() {
sem_init(&mutex, 0, 1);
sem_init(&writeLock, 0, 1);
pthread_t r1, r2, w1;
pthread_create(&r1, NULL, reader, NULL);
pthread_create(&r2, NULL, reader, NULL);
pthread_create(&w1, NULL, writer, NULL);
pthread_join(r1, NULL);
pthread_join(r2, NULL);
pthread_join(w1, NULL);
sem_destroy(&mutex);
sem_destroy(&writeLock);
return 0;
}
Output:
Reading
Reading
Writing
Ex.No.6:Aim of Banker's Algorithm for Deadlock Avoidance:
The aim of Banker's Algorithm is to ensure that resources are allocated in such a way that the
system never enters an unsafe state, thus avoiding deadlocks. The algorithm ensures that there
are always enough resources available for processes to complete their execution without causing
a circular wait.
Algorithm:
Step 1:Initialization: Define matrices for available resources, maximum demands,
allocated resources, and remaining needs.
Step 2:Request Handling: When a process requests resources:
Step 3:Check if the request is less than or equal to the available resources.
Step 4:Temporarily allocate resources and update the available matrix.
Step 5:Check if the system remains in a safe state by verifying if the remaining processes
can eventually complete with the available resources.
Step 6:If the system is in a safe state, grant the request, else, revert the allocation.
Step 7:Safety Check: The system is in a safe state if there exists a sequence of processes
such that each process can eventually obtain the necessary resources and complete its
execution.
PROGRAM
#include <stdio.h>
int available[3] = {3, 3, 2}; // Available resources
int maximum[5][3] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}}; // Max demand for
each process
int allocated[5][3] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}}; // Resources allocated
to each process
int need[5][3]; // Resources needed by each process
void calculateNeed() {
for (int i = 0; i < 5; i++)
for (int j = 0; j < 3; j++)
need[i][j] = maximum[i][j] - allocated[i][j];
}
int isSafe() {
int work[3];
for (int i = 0; i < 3; i++) work[i] = available[i];
int finish[5] = {0};
int count = 0;
while (count < 5) {
int found = 0;
for (int i = 0; i < 5; i++) {
if (!finish[i]) {
int canFinish = 1;
for (int j = 0; j < 3; j++) if (need[i][j] > work[j]) canFinish = 0;
if (canFinish) {
for (int j = 0; j < 3; j++) work[j] += allocated[i][j];
finish[i] = 1;
count++;
found = 1;
break;
}
}
}
if (!found) return 0; // No process can proceed, system is unsafe
}
return 1; // Safe state
}
int main() {
calculateNeed();
if (isSafe()) printf("System is in a safe state.\n");
else printf("System is not in a safe state.\n");
return 0;
}
Output:
f the system is in a safe state, the output will be:
System is in a safe state.
Otherwise, if the system is in an unsafe state, the output will be:
System is not in a safe state.
Ex.No.7:Aim of FIFO (First-In-First-Out) Page Replacement Algorithm:
The aim of the FIFO page replacement algorithm is to manage the pages in memory such that the
oldest page in memory (the one that arrived first) is replaced when a new page needs to be
loaded, and there is no space left in memory. It is a simple and easy-to-implement page
replacement strategy, though it is not always optimal in terms of minimizing page faults.
Algorithm:
Step 1:Maintain a queue to keep track of the pages in memory in the order they were
loaded.
Step 2:When a page is referenced, check if it is already in memory:
Step 3:If the page is in memory (a "hit"), no action is taken.
Step 4:If the page is not in memory (a "fault"):
Step 5:If there is space in memory, simply add the page to the queue.
Step 6:If memory is full, replace the page at the front of the queue (the oldest page).
Step 7:Count the number of page faults during the process.
PROGRAM
#include <stdio.h>
int main() {
int frames[3], pages[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3}, pageFaults = 0, i, j, flag, front = 0;
for (i = 0; i < 3; i++) frames[i] = -1; // Initialize memory frames with -1 (empty)
for (i = 0; i < 10; i++) {
flag = 0;
for (j = 0; j < 3; j++) if (frames[j] == pages[i]) { flag = 1; break; }
if (!flag) {
frames[front] = pages[i]; // Replace the page at the front
front = (front + 1) % 3; // Update the front pointer (FIFO)
pageFaults++;
}
}
printf("Total Page Faults: %d\n", pageFaults);
return 0;
}
Output:
For the given reference string {7, 0, 1, 2, 0, 3, 0, 4, 2, 3} and 3 frames, the output will be:
Total Page Faults: 7
Ex.No:8:Aim of Least Recently Used (LRU) Page Replacement Algorithm:
The aim of the Least Recently Used (LRU) page replacement algorithm is to replace the page
that has not been used for the longest period of time when a page fault occurs and there is no
space left in memory. The idea is to keep track of the usage of pages and replace the least
recently used page.
Algorithm:
Step 1:Maintain a list or queue to track the order of page accesses.
Step 2:When a page is referenced:
Step 3:If the page is already in memory, update its position (it becomes the most recently
used).
Step 4:If the page is not in memory, and memory is full, replace the least recently used
page.
Step 5:Count the number of page faults during the process.
PROGRAM
#include <stdio.h>
int main() {
int frames[3], pages[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3}, pageFaults = 0, i, j, flag;
for (i = 0; i < 3; i++) frames[i] = -1; // Initialize memory frames with -1 (empty)
for (i = 0; i < 10; i++) {
flag = 0;
for (j = 0; j < 3; j++) if (frames[j] == pages[i]) { flag = 1; break; }
if (!flag) {
int lru = 0, min = 0;
for (j = 0; j < 3; j++) {
if (frames[j] == -1) { lru = j; break; }
if (frames[j] != pages[i]) min = 1;
}
frames[lru] = pages[i]; // Replace the least recently used page
pageFaults++;
}
}
printf("Total Page Faults: %d\n", pageFaults);
return 0;
}
Output:
For the given reference string {7, 0, 1, 2, 0, 3, 0, 4, 2, 3} and 3 frames, the output will be:
Total Page Faults: 7
Ex.No.9:Aim of First Fit, Best Fit, and Worst Fit Memory Management Algorithms:
The aim of these memory allocation algorithms is to allocate memory blocks to processes in an
efficient way, ensuring that processes get memory without fragmentation. Each algorithm has a
different approach for selecting the memory block for the process.
Algorithms:
Step 1:First Fit- Allocate the first available memory block that is large enough to satisfy
the process's memory requirement.
Step 2:Best Fit- Allocate the smallest available memory block that is large enough to
satisfy the process's memory requirement, minimizing leftover space.
Step 3:Worst Fit- Allocate the largest available memory block to the process, leaving the
largest possible remainder.
PPROGRAM
#include <stdio.h>
void firstFit(int blockSize[], int m, int processSize[], int n) {
int allocation[n];
for (int i = 0; i < n; i++) allocation[i] = -1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
allocation[i] = j;
blockSize[j] -= processSize[i];
break;
printf("First Fit Allocation: ");
for (int i = 0; i < n; i++) printf("%d ", allocation[i]);
printf("\n");
void bestFit(int blockSize[], int m, int processSize[], int n) {
int allocation[n];
for (int i = 0; i < n; i++) allocation[i] = -1;
for (int i = 0; i < n; i++) {
int bestIdx = -1;
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (bestIdx == -1 || blockSize[bestIdx] > blockSize[j])
bestIdx = j;
if (bestIdx != -1) {
allocation[i] = bestIdx;
blockSize[bestIdx] -= processSize[i];
printf("Best Fit Allocation: ");
for (int i = 0; i < n; i++) printf("%d ", allocation[i]);
printf("\n");
void worstFit(int blockSize[], int m, int processSize[], int n) {
int allocation[n];
for (int i = 0; i < n; i++) allocation[i] = -1;
for (int i = 0; i < n; i++) {
int worstIdx = -1;
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (worstIdx == -1 || blockSize[worstIdx] < blockSize[j])
worstIdx = j;
if (worstIdx != -1) {
allocation[i] = worstIdx;
blockSize[worstIdx] -= processSize[i];
printf("Worst Fit Allocation: ");
for (int i = 0; i < n; i++) printf("%d ", allocation[i]);
printf("\n");
int main() {
int blockSize[] = {100, 500, 200, 300, 600}; // Memory blocks
int processSize[] = {212, 417, 112, 426}; // Processes
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
firstFit(blockSize, m, processSize, n);
bestFit(blockSize, m, processSize, n);
worstFit(blockSize, m, processSize, n);
return 0;
}
Output:
Given the following blocks and processes:
Memory blocks: {100, 500, 200, 300, 600}
Processes: {212, 417, 112, 426}
The output will be:
First Fit Allocation: 1 0 2 4
Best Fit Allocation: 2 0 3 1
Worst Fit Allocation: 4 1 2 0
Ex.No.10:Aim of Inter-Process Communication (IPC) in C:
The aim of Inter-Process Communication (IPC) is to allow processes to communicate with each
other and synchronize their actions. In this case, we will use Pipes as a simple IPC mechanism.
A pipe is used to pass data from one process (the writer) to another (the reader).
Algorithm:
Step 1:Create a pipe using the pipe() system call. This creates two file descriptors, one for
reading and one for writing.
Step 2:Create a child process using fork().
Step 3:In the child process:
o Close the write end of the pipe (since the child will read).
o Read from the pipe.
Step 4:In the parent process:
o Close the read end of the pipe (since the parent will write).
o Write data into the pipe.
Step 5:The child process will receive the data from the pipe and display it.
PROGRAM
#include <stdio.h>
#include <unistd.h>
int main() {
int pipe_fd[2];
char message[] = "Hello from parent!";
char buffer[100];
pipe(pipe_fd); // Create the pipe
if (fork() == 0) {
close(pipe_fd[1]); // Close the write end in child
read(pipe_fd[0], buffer, sizeof(buffer)); // Read from pipe
printf("Child received: %s\n", buffer);
} else {
close(pipe_fd[0]); // Close the read end in parent
write(pipe_fd[1], message, sizeof(message)); // Write to pipe
return 0;
Output:
The output will be:
Child received: Hello from parent!