0% found this document useful (0 votes)
10 views

OS file(1-4)_final

The document is a practical file for an Operating Systems Lab course, detailing various scheduling algorithms including FCFS, SRTF, and SJF. It includes theoretical explanations, algorithms, sample C code implementations, and viva questions related to each scheduling method. The file is submitted by a student and outlines experiments conducted in the lab.

Uploaded by

aakshargarg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

OS file(1-4)_final

The document is a practical file for an Operating Systems Lab course, detailing various scheduling algorithms including FCFS, SRTF, and SJF. It includes theoretical explanations, algorithms, sample C code implementations, and viva questions related to each scheduling method. The file is submitted by a student and outlines experiments conducted in the lab.

Uploaded by

aakshargarg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

PRACTICAL FILE

OF
Operating Systems Lab
(Paper code: AIML-351)

MAHARAJA AGRASEN INSTITUTE OF


TECHNOLOGY SECTOR-22, ROHINI, NEW DELHI
Submitted to: Submitted by:
Dr. Neelam Sharma Name:Aakshar Ruchin
Garg
Assistant Professor Roll No: 35314811622
AI and ML Dept. Semester-5th

Group-AIML-2
INDEX
Exp. Experiment Date of R1 R2 R3 R4 R5 Total Remarks Signature
Name performin
No. g Marks

(15)

1.

2.

3.

4.

5.

6.

7.

8.

9.
PROGRAM NO. 1
AIM: Write a C program to implement a FCFS scheduling algorithm.
THEORY:
First Come First Serve:
FCFS considered to be the simplest of all operating system scheduling algorithms. First come
first serve scheduling algorithm states that the process that requests the CPU first is allocated
the CPU first and is implemented by using FIFO queue.
Characteristics of FCFS
• FCFS supports non-preemptive and preemptive CPU scheduling algorithms.
• Tasks are always executed on a First-come, First-serve concept.
• FCFS is easy to implement and use.
• This algorithm is not much efficient in performance, and the wait time is quite high.
Advantages of FCFS
• Easy to implement
• First come, first serve method
Disadvantages of FCFS
• FCFS suffers from Convoy effect.
• The average waiting time is much higher than the other algorithms.
• FCFS is very simple and easy to implement and hence not much efficient.

ALGORITHM:
1. Create a queue to get the requests or processes that must be stored to execute.

2. On the arrival of a new process, it is placed at the end of the queue.

3. If the CPU is idle, assign the request or process at the front of the queue to the CPU for

processing.
4. But in case the CPU is busy, wait until the current process is finished processing.

5. As the execution of the current process is done, it is removed from the FIFO queue, and the

next process at the front of the queue is put forward for execution.
6. Repeat steps 3 to 5 until all processes have been serviced.

CODE:
#include <stdio.h>
void findWaitingTime(int processes[], int n, int bt[], int wt[]) {
wt[0] = 0;
for (int i = 1; i < n; i++) { wt[i]
= bt[i - 1] + wt[i - 1];
}}
void findTurnAroundTime(int processes[], int n, int bt[], int wt[], int tat[]) {
for (int i = 0; i < n; i++) { tat[i] = bt[i] + wt[i];
}}
void findAvgTime(int processes[], int n, int bt[]) {
int wt[n], tat[n]; int total_wt = 0, total_tat = 0;
findWaitingTime(processes, n, bt, wt);
findTurnAroundTime(processes, n, bt, wt, tat);
printf("Processes Burst time Waiting time Turn around time\n"); for
(int i = 0; i < n; i++) {
total_wt += wt[i];
total_tat += tat[i];
printf(" %d ", (i + 1));
printf(" %d ", bt[i]);
printf(" %d ", wt[i]);
printf(" %d\n", tat[i]);
}
float avg_wt = (float)total_wt / (float)n; float avg_tat =
(float)total_tat / (float)n; printf("The output of the algorithm
printed by Aakshar Garg: "); printf("Average waiting time =
%.2f\n", avg_wt); printf("Average turn around time =
%.2f\n", avg_tat);
} int main()
{
int processes[] = {7, 8, 9};
int n = sizeof(processes) / sizeof(processes[0]);
int burst_time[] = {1,2,3};
findAvgTime(processes, n, burst_time); return
0;
}

OUTPUT:

VIVA QUESTIONS:
Q1. What is the purpose of the First Come First Serve (FCFS) scheduling algorithm in
operating systems?
ANS. The FCFS scheduling algorithm is used to manage the execution order of processes in
the system. It schedules processes based on their arrival time, executing the process that
arrives first without preemption until it completes.
Q2. How would you define a process structure in C for implementing the FCFS
scheduling algorithm?
ANS. A process structure in C for FCFS might include fields for process ID, arrival time, burst
time, completion time, and waiting time. For example:
struct Process { int pid;
int arrivalTime; int
burstTime; int
completionTime; int
waitingTime;
};
Q3. Describe the key steps involved in implementing the FCFS scheduling algorithm in
C.
ANS. The key steps are:
1. Define a structure for processes.
2. Take input for the number of processes and their respective arrival and burst times.
3. Sort the processes based on arrival time.
4. Calculate the completion time for each process.
5. Compute the waiting time and turn around time for each process.
6. Output the results.
Q4. How do you calculate the waiting time for each process in the FCFS scheduling
algorithm?
ANS. Waiting Time = Completion Time - Arrival Time - Burst Time
Q5. How do you calculate the turn around time for each process in the FCFS scheduling
algorithm?
ANS. Turn Around Time = Completion Time - Arrival Time

PROGRAM NO. 2(a)


AIM: To implement Preemptive Shortest Remaining Time First (SRTF) algorithm.
THEORY:
In the Shortest Remaining Time First (SRTF) scheduling algorithm, the process with the
smallest amount of time remaining until completion is selected to execute. Since the currently
executing process is the one with the shortest amount of time remaining by definition, and
since that time should only reduce as execution progresses, processes will always run until
they complete or a new process is added that requires a smaller amount of time.
Some of the key characteristics of SRTF :
• Preemptive: SRTF is a preemptive algorithm, which means that the currently running
process can be interrupted if a new process arrives with a shorter burst time. This
helps in ensuring that the processes with the shortest burst times are executed first.
• Dynamic: SRTF is a dynamic algorithm, which means that it can adapt to changes in
the arrival time and burst time of processes. It constantly re-evaluates the remaining
burst time of each process and schedules the process with the shortest remaining
time.
• Low waiting time: SRTF is known for its low waiting time. By selecting the process
with the shortest remaining burst time, it ensures that the processes with the shortest
burst times are executed first, which reduces the average waiting time of processes.
• SRTF has a higher complexity than other scheduling algorithms like FCFS (First
Come First Serve) and RR (Round Robin), because it requires frequent context
switches and preemptions.

ALGORITHM:
1. Traverse until all process gets completely executed.

o Find process with minimum remaining time at every single time lap.
o Reduce its time by 1.
o Check if its remaining time becomes 0 o Increment the
counter of process completion.
o Completion time of current process = current_time + 1; o
Calculate waiting time for each completed process.
o wt[i]= Completion time – arrival_time-burst_time
o Increment time lap by one.
2. Find turnaround time (waiting_time + burst_time).

CODE:
#include <stdio.h>
#include <limits.h>
struct Process {
int pid;
int bt; int
art; };
void findWaitingTime(struct Process proc[], int n, int wt[]) {
int rt[n]; for (int i = 0; i
< n; i++)
rt[i] = proc[i].bt;
int complete = 0, t = 0, minm =
INT_MAX; int shortest = 0, finish_time;
int check = 0; while (complete != n) {
for (int j = 0; j < n; j++) {
if ((proc[j].art <= t) &&
(rt[j] < minm) && rt[j] > 0) {
minm = rt[j]; shortest = j;
check = 1;
} } if (check
== 0) {
t++; continue; }
rt[shortest]--; minm
= rt[shortest]; if
(minm == 0)

minm = INT_MAX;
if (rt[shortest] == 0) {
complete++; check = 0;
finish_time = t + 1;
wt[shortest] = finish_time
- proc[shortest].bt -
proc[shortest].art;
if (wt[shortest] < 0)
wt[shortest] = 0;
}
t++;
}}
void findTurnAroundTime(struct Process proc[], int n, int wt[], int tat[]) {
for (int i = 0; i < n; i++)
tat[i] = proc[i].bt + wt[i];
}
void findavgTime(struct Process proc[], int n) {
int wt[n], tat[n], total_wt = 0,
total_tat = 0;
findWaitingTime(proc, n, wt);
findTurnAroundTime(proc, n, wt, tat);
printf(" P\t\t"
"BT\t\t"
"WT\t\t"
"TAT\t\t\n"); for (int i =
0; i < n; i++) {
total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i]; printf("
%d\t\t"
"%d\t\t %d"
"\t\t %d\n", proc[i].pid, proc[i].bt,
wt[i], tat[i]);
}
printf("The output of the algorithm by Aakshar Garg:");
printf("\nAverage waiting time = "
"%f", (float)total_wt / (float)n); printf("\nAverage
turn around time = "
"%f", (float)total_tat / (float)n);
} int main()
{
struct Process proc[] = { { 1, 7, 2 }, { 2, 9, 5 },
{ 3, 8, 1 }, { 4, 3, 0}, {5, 3, 4} };
int n = sizeof(proc) / sizeof(proc[0]);
findavgTime(proc, n); return 0;
}

OUTPUT:
VIVA QUESTIONS:
Q1. What is the key difference between SRTF and SJF scheduling algorithms?
ANS. The key difference is that SRTF is preemptive, meaning it can interrupt a running
process if a new process arrives with a shorter remaining burst time. In contrast, SJF
(Shortest Job First) is non-preemptive, so once a process starts executing, it runs to
completion without being interrupted.
Q2. How do you handle the arrival of a new process in the SRTF algorithm?
ANS. When a new process arrives, the algorithm checks if the remaining burst time of the
currently executing process is greater than the burst time of the new process. If it is, the
current process is preempted, and the new process is scheduled to run. The preempted process
is then added back to the ready queue with its remaining burst time.
Q3. What data structure is commonly used to manage the ready queue in the SRTF
algorithm?
ANS. A priority queue or a min-heap is commonly used to manage the ready queue in SRTF.
The queue is sorted based on the remaining burst time of the processes, with the process
having the shortest remaining time at the front.
Q4. How do you calculate the waiting time for each process in SRTF?
ANS. The waiting time for a process in SRTF is calculated by subtracting its burst time from
the turnaround time, which is the total time from the process's arrival until its completion.
Waiting time can also be calculated incrementally by keeping track of the total time a process
spends in the ready queue.
Q5. Why is SRTF considered an optimal scheduling algorithm in terms of average
waiting time?
ANS. SRTF is considered optimal for minimizing the average waiting time because it always
schedules the process that has the shortest remaining time to finish. This approach ensures
that processes with shorter burst times are completed sooner, reducing the overall waiting
time for other processes in the queue.

PROGRAM NO. 2(b)


AIM: To implement Non-preemptive Shortest Job First (SJF) algorithm.
THEORY:

The shortest job first (SJF) or shortest job next, is a scheduling policy that selects the waiting
process with the smallest execution time to execute next. SJN, also known as Shortest Job
Next (SJN), can be preemptive or non-preemptive.
Characteristics of SJF Scheduling:
• Shortest Job first has the advantage of having a minimum average waiting time among
all scheduling algorithms.
• It is a Greedy Algorithm.
• It may cause starvation if shorter processes keep coming. This problem can be solved
using the concept of ageing.
• It is practically infeasible as Operating System may not know burst times and therefore
may not sort them. While it is not possible to predict execution time, several methods
can be used to estimate the execution time for a job, such as a weighted average of
previous execution times.
• SJF can be used in specialized environments where accurate estimates of running time
are available.

ALGORITHM:
• Sort all the processes according to the arrival time.
• Then select that process that has minimum arrival time and minimum Burst time.
• After completion of the process make a pool of processes that arrives afterward till the
completion of the previous process and select that process among the pool which is
having minimum Burst time.

CODE:
#include <stdio.h> int
main()
{ int A[100][4];
int i, j, n, total = 0, index, temp; float
avg_wt, avg_tat; printf("Enter
number of process: "); scanf("%d",
&n); printf("Enter Burst Time:\n");
for (i = 0; i < n; i++) { printf("P%d:
", i + 1);
scanf("%d", &A[i][1]);
A[i][0] = i + 1; } for (i =
0; i < n; i++) {
index = i; for (j = i + 1;
j < n; j++)
if (A[j][1] < A[index][1])
index = j;
temp = A[i][1];
A[i][1] = A[index][1]; A[index][1]
= temp;

temp = A[i][0];
A[i][0] = A[index][0];
A[index][0] = temp;
}
A[0][2] = 0; for (i = 1;
i < n; i++) { A[i][2] =
0; for (j = 0; j < i; j++)
A[i][2] += A[j][1]; total
+= A[i][2];
} avg_wt = (float)total /
n; total = 0;

printf("P BT WT TAT\n");
for (i = 0; i < n; i++) { A[i][3]
= A[i][1] + A[i][2]; total
+= A[i][3];
printf("P%d %d %d %d\n", A[i][0],
A[i][1], A[i][2], A[i][3]);
}
avg_tat = (float)total / n; printf("The output of the
algorithm printed by Aakshar Garg: "); printf("Average
Waiting Time= %f", avg_wt); printf("\nAverage
Turnaround Time= %f", avg_tat);
}

OUTPUT:
VIVA QUESTIONS:
Q1. What is the main characteristic of the Shortest Job First (SJF) scheduling
algorithm?
ANS. The main characteristic of the SJF scheduling algorithm is that it selects the process
with the shortest burst time from the ready queue for execution next. This approach
minimizes the average waiting time for processes.
Q2. Is SJF a preemptive or non-preemptive scheduling algorithm?
ANS. SJF is generally a non-preemptive scheduling algorithm, meaning that once a process
starts executing, it runs to completion without being interrupted. However, there is a
preemptive version called Shortest Remaining Time First (SRTF).
Q3. How do you handle processes with the same burst time in the SJF algorithm?
ANS. When multiple processes have the same burst time, SJF typically uses the process
arrival time as a tiebreaker, selecting the process that arrived first. If arrival times are also
the same, the processes can be scheduled in the order they appear in the input. Q4. What is
the key advantage of using the SJF scheduling algorithm?
ANS. The key advantage of SJF is that it minimizes the average waiting time for processes,
which can lead to more efficient CPU utilization compared to other scheduling algorithms like
First-Come, First-Served (FCFS).
Q5. How is the turnaround time calculated for each process in SJF?
ANS. The turnaround time for a process in SJF is calculated as the difference between the
completion time and the arrival time of the process. Turnaround Time = Completion Time -
Arrival Time. This value represents the total time taken from the arrival of the process to its
completion.

PROGRAM NO. 3
AIM: To implement

a) Preemptive Round Robin Algorithm


b) Non-Preemptive Round Robin Algorithm

THEORY:
a) The Round Robin (RR) scheduling algorithm is a popular CPU scheduling algorithm used in
operating systems, especially in time-sharing systems. It is designed to ensure that all processes
are given an equal share of CPU time and is particularly effective for providing fair and
responsive task management.
Basic Round Robin Algorithm
In the Round Robin algorithm:
1. Time Quantum (Time Slice): A fixed time period, known as the time quantum, is assigned
to each process in the ready queue. This time quantum is usually small to keep the system
responsive.
2. Cyclic Execution: Processes are scheduled in a cyclic order. Each process gets the CPU for
a maximum of one time quantum. If a process completes its execution within the time quantum,
it releases the CPU voluntarily. If not, it is preempted and placed at the end of the ready queue,
and the CPU is assigned to the next process in the queue.
3. Fairness and Response Time: This ensures that all processes get a fair share of the CPU
and that no process can monopolize CPU time. It also provides good response times for
interactive processes.
a) Preemptive Round Robin Algorithm
Preemptive Nature: The preemptive nature of Round Robin means that a process can be
interrupted and moved back to the ready queue if it has not completed within its assigned time
quantum. The CPU is then given to the next process in line.
Process Flow:
1. The scheduler picks the first process in the ready queue and allows it to run for one time
quantum.
2. If the process finishes before the quantum ends, it releases the CPU.
3. If the process is still running when the quantum expires, it is preempted and placed at the
end of the ready queue.
4. The next process in the ready queue is then scheduled.
Advantages:
1. Provides a fair allocation of CPU time.

2. Reduces starvation since every process gets a turn.

3. Suitable for time-sharing systems.

Disadvantages:
1. High context-switching overhead if the time quantum is too small.

2. Poor throughput if the time quantum is too large or too small.

b) Non-Preemptive Round Robin Algorithm


1. Non-Preemptive Nature: A true non-preemptive version of Round Robin does not exist
because Round Robin fundamentally relies on preemption to cycle through processes based on
the time quantum.
2. Behavior in Non-Preemptive Context: In a non-preemptive system, once a process starts
executing, it continues until it finishes or enters a waiting state (like I/O operations). This
behavior is incompatible with the basic principles of Round Robin, which relies on time
quantums to interrupt and cycle through processes.

ALGORITHM:
1. Initialize Variables:
i) Store the burst times of processes in an array.
ii) Initialize the remaining burst times array with burst times. iii) Set current
time (currentTime) to zero.
2. Iterate Over Processes in a Round Robin Manner:
i) Use a loop that continues until all processes are completed.
ii) For each process: iii) Check if the process has remaining burst time.
iv) If the remaining burst time is greater than the time quantum, execute the process for the
time quantum, reduce its remaining time, and increment the current time.
v) If the remaining burst time is less than or equal to the time quantum, execute the process
until completion, update the waiting time, and set the remaining time to zero.
3. Check for Completion: If all processes are completed (remaining burst times are zero), exit
the loop.
4. Calculate Turnaround Time: For each process, calculate turnaround time as the sum of burst
time and waiting time.
5. Calculate Averages: Calculate and display the average waiting time and turnaround time
for all processes.
CODE:
a)
#include <stdio.h>
#define MAX 10
typedef struct { int id;
int burst_time; int
remaining_time; int
waiting_time; int
turnaround_time;
} Process; void round_robin(Process processes[], int n, int
time_quantum) { int time = 0; int completed = 0; while
(completed < n) { for (int i = 0; i < n; i++) {
if (processes[i].remaining_time > 0) {
if (processes[i].remaining_time > time_quantum) {
time += time_quantum;
processes[i].remaining_time -= time_quantum;
} else { time += processes[i].remaining_time;
processes[i].turnaround_time = time;
processes[i].waiting_time = time - processes[i].burst_time;
processes[i].remaining_time = 0; completed++;
}
}
}
} } int main() { int n, time_quantum;
Process processes[MAX]; printf("Enter the
number of processes: "); scanf("%d", &n);
for (int i = 0; i < n; i++) { processes[i].id = i + 1;
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &processes[i].burst_time);
processes[i].remaining_time =
processes[i].burst_time;
} printf("Enter time quantum: "); scanf("%d", &time_quantum);
round_robin(processes, n, time_quantum); printf("\nProcess\tBurst
Time\tWaiting Time\tTurnaround Time\n"); for (int i = 0; i < n; i++) {
printf("%d\t%d\t\t%d\t\t%d\n", processes[i].id, processes[i].burst_time,
processes[i].waiting_time, processes[i].turnaround_time);
} return
0;
}
b)
#include <stdio.h>
#define MAX 10
typedef struct { int id;
int burst_time; int
waiting_time; int
turnaround_time;
} Process; void round_robin_non_preemptive(Process
processes[], int n) {
int time = 0; for (int i = 0;
i < n; i++) {
// Run each process until it completes (non-preemptive)
processes[i].waiting_time = time; time +=
processes[i].burst_time; processes[i].turnaround_time
= time;
} } int
main() { int
n;
Process processes[MAX]; printf("Enter
the number of processes: "); scanf("%d",
&n);
for (int i = 0; i < n; i++) {
processes[i].id = i + 1; printf("Enter burst time
for process %d: ", i + 1); scanf("%d",
&processes[i].burst_time);
} round_robin_non_preemptive(processes, n); printf("\nProcess\tBurst
Time\tWaiting Time\tTurnaround Time\n"); for (int i = 0; i < n; i++) {
printf("%d\t%d\t\t%d\t\t%d\n", processes[i].id, processes[i].burst_time,
processes[i].waiting_time, processes[i].turnaround_time);
} return
0;
}
OUTPUT:
a)

b)
VIVA QUESTIONS:
Q1. What is the purpose of the time quantum in the Preemptive Round Robin
algorithm?
ANS. The time quantum is the fixed time slice that each process is allowed to run before being
preempted and moved to the end of the queue.
Q2. How does the Preemptive Round Robin algorithm handle processes that exceed
their time quantum?
ANS. If a process exceeds its time quantum, it is preempted and placed at the end of the ready
queue, allowing the next process to run.
Q3. What happens to the waiting time of a process in the Non-Preemptive Round Robin-
like algorithm?
ANS. In the Non-Preemptive Round Robin-like algorithm (similar to FCFS), waiting time
accumulates as each process waits for all prior processes to complete without interruption.
Q4. Why can't a true Non-Preemptive Round Robin algorithm exist?
ANS. A true Non-Preemptive Round Robin cannot exist because Round Robin relies on
preemption to cycle through processes using the time quantum, which is not possible in non-
preemptive scheduling.
Q5. What is the main advantage of using the Preemptive Round Robin algorithm?
ANS. The main advantage is fairness, as all processes receive equal CPU time, and it prevents
any single process from monopolizing the CPU, enhancing responsiveness.

PROGRAM NO. 4
AIM: To implement

a) Preemptive Priority Scheduling Algorithm


b) Non-Preemptive Priority Scheduling Algorithm
THEORY:
Priority scheduling is a type of scheduling algorithm in operating systems where each process
is assigned a priority. Processes are scheduled based on their priority rather than on their arrival
time or any other criteria. The key idea is that processes with higher priority are executed before
processes with lower priority. This can be applied in both preemptive and non-preemptive
modes.

a) Preemptive Priority Scheduling: In preemptive priority scheduling, the operating system may
preempt a currently running process if a new process with a higher priority arrives. This means
that if a higher priority process becomes ready to run while another process is running, the CPU
will switch from the currently running process to the higher priority process. This allows the
system to respond quickly to high-priority processes, but it can also lead to high-priority
processes frequently interrupting lower-priority ones.

Characteristics:
i) The running process can be interrupted.

ii) Higher priority processes can preempt the current running process.

iii) It offers better response time for high-priority processes. iv) May lead to frequent context

switching, which can increase overhead.


v) Can cause starvation, where low-priority processes may never get executed if high-priority
processes keep arriving.
b) Non-Preemptive Priority Scheduling:In non-preemptive priority scheduling, the CPU is
assigned to a process until it completes its execution or switches to the waiting state. If a process
with a higher priority arrives while another process is running, it will wait until the current
process finishes its CPU burst. The scheduler only assigns the CPU to the process with the
highest priority among the ready processes.

Characteristics:
i) The running process cannot be interrupted by another process.

ii) The CPU is only assigned to a process when the current process finishes its execution or
moves to a waiting state.
iii) It has less overhead because context switching is minimized. iv) Can also cause starvation

of lower-priority processes.
v) More predictable because once a process starts running, it continues until it's done.

Starvation and Solution:


Starvation: In both preemptive and non-preemptive priority scheduling, starvation is a
significant problem where low-priority processes may never get executed if higher-priority
processes keep arriving. This issue arises because processes with lower priorities can be
perpetually postponed.

Solution (Aging): A common solution to prevent starvation is aging, which gradually increases
the priority of a process the longer it waits in the system. Over time, even low-priority processes
gain higher priority, ensuring they eventually get scheduled.

Priority scheduling is widely used in scenarios where certain tasks must be prioritized, such as
real-time systems, but care must be taken to handle starvation issues effectively.
CODE:
(a)
#include <stdio.h>
struct Process { int
pid; int burstTime; int
priority; int
arrivalTime; int
remainingTime;
};
void preemptivePriorityScheduling(struct Process processes[], int n) {
int currentTime = 0; int
completed = 0; int
shortest = 0; int
minPriority; while
(completed != n) {
minPriority = 9999;
shortest = -1; for (int i =
0; i < n; i++) {
if (processes[i].arrivalTime <= currentTime &&
processes[i].remainingTime > 0 &&
processes[i].priority < minPriority) {
minPriority = processes[i].priority;
shortest = i;
}}
if (shortest == -1) {
currentTime++;
continue;
}
processes[shortest].remainingTime--; if
(processes[shortest].remainingTime == 0) {
completed++;
printf("Process %d finished at time %d\n", processes[shortest].pid, currentTime + 1);
}
currentTime++;
} } int main() { struct
Process processes[] = {
{1, 7, 1, 0, 10},
{2, 1, 3, 2, 9},
{3, 0, 2, 1, 2},
};
int n = sizeof(processes) / sizeof(processes[0]);
printf("Preemptive Priority Scheduling algorithm output printed by Aakshar
Garg:\n"); preemptivePriorityScheduling(processes, n); return 0;
}
(b)
#include <stdio.h>
struct Process { int
pid; int burstTime; int
priority; int
arrivalTime; int
waitingTime; int
turnaroundTime; int
isCompleted;
};
void nonPreemptivePriorityScheduling(struct Process processes[], int n) {
int currentTime = 0; int completed = 0; int shortest = 0; int minPriority;
while (completed != n) { minPriority = 9999; shortest = -1; for (int i =
0; i < n; i++) { if (processes[i].arrivalTime <= currentTime &&
!processes[i].isCompleted &&
processes[i].priority < minPriority)
{ minPriority = processes[i].priority;
shortest = i;
}}
if (shortest == -1) {
currentTime++;
continue;
}
currentTime += processes[shortest].burstTime;
processes[shortest].turnaroundTime = currentTime - processes[shortest].arrivalTime;
processes[shortest].waitingTime = processes[shortest].turnaroundTime -
processes[shortest].burstTime;
processes[shortest].isCompleted = 1;
completed++;
printf("Process %d finished at time %d\n", processes[shortest].pid, currentTime);
} } int main() { struct
Process processes[] = { {1, 7, 1,
0, 0, 0, 0},

{2, 1, 3, 2, 0, 1, 0},
{3, 2, 2, 1, 0, 2, 0},
};
int n = sizeof(processes) / sizeof(processes[0]);
printf("Non-Preemptive Priority Scheduling Algorithm output printed by Aakshar
Garg:\n"); nonPreemptivePriorityScheduling(processes, n); return 0;
}

OUTPUT:
(a)

(b)

VIVA-QUESTIONS:
Q1. What is the main difference between Preemptive and Non-Preemptive Priority
Scheduling?
ANS. In Preemptive Priority Scheduling, a running process can be interrupted if a higher-
priority process arrives. In Non-Preemptive Priority Scheduling, the running process cannot
be interrupted; the CPU is only assigned to a higher-priority process after the current process
finishes.
Q2. How do you handle the issue of starvation in Priority Scheduling?
ANS. Starvation can be handled using aging, where the priority of a process is gradually
increased the longer it waits in the queue, ensuring that even low-priority processes
eventually get executed.
Q3. In a Preemptive Priority Scheduling implementation, what triggers a context
switch?
ANS. A context switch is triggered when a new process with a higher priority than the currently
running process arrives in the ready queue.
Q4. What data structure can be used to manage the processes in Priority Scheduling?
ANS. A priority queue or a sorted list can be used to manage processes, where processes are
ordered based on their priority.
Q5. How does Non-Preemptive Priority Scheduling determine the next process to
execute when the CPU becomes idle?
ANS. When the CPU becomes idle, Non-Preemptive Priority Scheduling selects the process
with the highest priority from the ready queue and assigns it to the CPU for execution.

You might also like