You are on page 1of 33

GURU TEGH BAHADUR INSTITUTE OF

TECHNOLOGY

Operating Systems

Practical File

Artificial Intelligence & Data Science(AI-DS)


Semester 5

Submitted to:- Submitted by :-PRAKHAR SHARMA

Ms Monika Srivastava ENROLLMENT - 50113211931

BRANCH -AIDS
INDEX

S.NO. EXPERIMENT DATE SIGNATURE


C program to implement FCFS
1. scheduling algorithm.
C program to implement a round robin
2. scheduling algorithm.
Implementation of the following Memory
3. Allocation Methods for fixed partition
a) First Fit b) Worst Fit c) Best Fit
Program to implement reader/writer
4. problems using semaphores.
5. Program to implement Banker’s
algorithm for deadlock avoidance.
6. Process Management

7. C program to implement a Shortest Job


First scheduling algorithm.

8. C program to implement a priority


scheduling algorithm.
EXPERIMENT – 1

AIM: C program to implement FCFS scheduling algorithm.

THEORY:

FCFS is the first algorithm of CPU Process Scheduling Algorithm. In First Come First Serve
Algorithm what we do is to allow the process to execute in linear manner.

This means that whichever process enters process enters the ready queue first is executed
first. This shows that First Come First Serve Algorithm follows First In First Out (FIFO)
principle. The First Come First Serve Algorithm can be executed in Pre Emptive and Non Pre
Emptive manner.

The characteristics of FCFS CPU Process Scheduling are:

1. Implementation is simple.
2. Does not cause any causalities while using
3. It adopts a non pre-emptive and pre-emptive strategy.
4. It runs each procedure in the order that they are received.
5. Arrival time is used as a selection criterion for procedures.

Waiting Time = Turnaround Time – Burst Time


Turnaround Time = Completion Time – Arrival Time

FCFS Scheduling Algorithm:

1. Enter all the processes and their burst time.


2. Find waiting time, WT of all the processes.
3. For the 1st process, WT = 0.
4. For all the next processes i, WT[i] = BT[i-1] + WT[i-1].
5. Calculate Turnaround time = WT + BT for all the processes.
6. Calculate average waiting time = total waiting time/no. of processes.
7. Calculate average turnaround time = total turnaround time/no. of processes.
PROGRAM:
1. #include <stdio.h>
2. int main()
3. {
4. int pid[15];
5. int bt[15];
6. int n;
7. printf("Enter the number of processes: ");
8. scanf("%d",&n);
9.
10. printf("Enter process id of all the processes: ");
11. for(int i=0;i<n;i++)
12. {
13. scanf("%d",&pid[i]);
14. }
15.
16. printf("Enter burst time of all the processes: ");
17. for(int i=0;i<n;i++)
18. {
19. scanf("%d",&bt[i]);
20. }
21.
22. int i, wt[n];
23. wt[0]=0;
24.
25. //for calculating waiting time of each process
26. for(i=1; i<n; i++)
27. {
28. wt[i]= bt[i-1]+ wt[i-1];
29. }
30.
31. printf("Process ID Burst Time Waiting Time TurnAround Time\n");
32. float twt=0.0;
33. float tat= 0.0;
34. for(i=0; i<n; i++)
35. {
36. printf("%d\t\t", pid[i]);
37. printf("%d\t\t", bt[i]);
38. printf("%d\t\t", wt[i]);
39.
40. //calculating and printing turnaround time of each process
41. printf("%d\t\t", bt[i]+wt[i]);
42. printf("\n");
43.
44. //for calculating total waiting time
45. twt += wt[i];
46.
47. //for calculating total turnaround time
48. tat += (wt[i]+bt[i]);
49. }
50. float att,awt;
51.
52. //for calculating average waiting time
53. awt = twt/n;
54.
55. //for calculating average turnaround time
56. att = tat/n;
57. printf("Avg. waiting time= %f\n",awt);
58. printf("Avg. turnaround time= %f",att);
59. }

OUTPUT:
(EXP-1 : FCFS Scheduling)
EXPERIMENT – 2
AIM: C program to implement a round robin scheduling algorithm.

THEORY:
Round Robin Scheduling is a CPU scheduling algorithm in which each process is executed
for a fixed time slot. Since the resources are snatched after the time slot, round robin is pre-
emptive.
Pre-emptive: In this type, resources can be voluntarily snatched.
Non-Pre-emptive: In this type, if a process is once started, it will execute completely i.e
resources cannot be snatched.

Characteristics of Round Robin


1. It is a pre-emptive algorithm.
2. It shares an equal time interval between all processes to complete their task.
3. It is a starvation free CPU scheduling algorithm. Hence it is known as the fairest and
simple algorithm.

Following are the basic terminologies:

Turnaround Time: Difference between completion time and arrival time.


Turnaround Time = Completion Time – Arrival Time

Waiting Time: Time Difference between turnaround time and burst time.
Waiting Time = Turnaround Time – Burst Time

Round Robin Scheduling Algorithm:


Step 1: Start the Program.
Step 2: Input the number of processes.
Step 3: Input the burst time and arrival time of each process and the limit of the time slot.
Step 4: Push all processes into the ready queue according to their arrival time. Then execute
each process upto time slot and push left over process in queue again for execution.
Step 5: After a process is completely executed, print its turn around time and waiting time.

PROGRAM:

1. #include<stdio.h>
2. #include<conio.h>
3. void main()
4. {
5. // initlialize the variable name
6. int i, NOP, sum=0,count=0, y, quant, wt=0, tat=0, at[10], bt[10], temp[10];
7. float avg_wt, avg_tat;
8. printf(" Total number of process in the system: ");
9. scanf("%d", &NOP);
10. y = NOP; // Assign the number of process to variable y
11.
12. // Use for loop to enter the details of the process like Arrival time and the Burst Time
13. for(i=0; i<NOP; i++)
14. {
15. printf("\n Enter the Arrival and Burst time of the Process[%d]\n", i+1);
16. printf(" Arrival time is: \t"); // Accept arrival time
17. scanf("%d", &at[i]);
18. printf(" \nBurst time is: \t"); // Accept the Burst time
19. scanf("%d", &bt[i]);
20. temp[i] = bt[i]; // store the burst time in temp array
21. }
22. // Accept the Time qunat
23. printf("Enter the Time Quantum for the process: \t");
24. scanf("%d", &quant);
25. // Display the process No, burst time, Turn Around Time and the waiting time
26. printf("\n Process No \t\t Burst Time \t\t TAT \t\t Waiting Time ");
27. for(sum=0, i = 0; y!=0; )
28. {
29. if(temp[i] <= quant && temp[i] > 0) // define the conditions
30. {
31. sum = sum + temp[i];
32. temp[i] = 0;
33. count=1;
34. }
35. else if(temp[i] > 0)
36. {
37. temp[i] = temp[i] - quant;
38. sum = sum + quant;
39. }
40. if(temp[i]==0 && count==1)
41. {
42. y--; //decrement the process no.
43. printf("\nProcess No[%d] \t\t %d\t\t\t\t %d\t\t\t %d", i+1, bt[i], sum-at[i], sum-
at[i]-bt[i]);
44. wt = wt+sum-at[i]-bt[i];
45. tat = tat+sum-at[i];
46. count =0;
47. }
48. if(i==NOP-1)
49. {
50. i=0;
51. }
52. else if(at[i+1]<=sum)
53. {
54. i++;
55. }
56. else
57. {
58. i=0;
59. }
60. }
61. // represents the average waiting time and Turn Around time
62. avg_wt = wt * 1.0/NOP;
63. avg_tat = tat * 1.0/NOP;
64. printf("\n Average Turn Around Time: \t%f", avg_wt);
65. printf("\n Average Waiting Time: \t%f", avg_tat);
66. getch();
67. }
OUTPUT:
(EXP-2 : Round Robin Scheduling)
EXPERIMENT – 3

AIM: Implementation of the following Memory Allocation Methods for fixed partition
a) First Fit b) Worst Fit c) Best Fit.

THEORY:
1. First Fit: In the first fit, the partition is allocated which is the first sufficient block
from the top of Main Memory. It scans memory from the beginning and chooses the
first available block that is large enough. Thus it allocates the first hole that is large
enough.
2. Best Fit Allocate the process to the partition which is the first smallest sufficient
partition among the free available partition. It searches the entire list of holes to find
the smallest hole whose size is greater than or equal to the size of the process.
3. Worst Fit Allocate the process to the partition which is the largest sufficient among
the freely available partitions available in the main memory. It is opposite to the
best-fit algorithm. It searches the entire list of holes to find the largest hole and
allocate it to process.

FIRST FIT MEMORY ALLOCATION:


Implementation:
1. Input memory blocks with size and processes with size.
2. Initialize all memory blocks as free.
3. Start by picking each process and check if it can be assigned to current block.
4. If size-of-process <= size-of-block if yes then assign and check for next process.
5. If not then keep checking the further blocks.

Program:

// C implementation of First - Fit algorithm


#include<stdio.h>

// Function to allocate memory to


// blocks as per First fit algorithm
void firstFit(int blockSize[], int m, int processSize[], int n)
{
int i, j;
// Stores block id of the
// block allocated to a process
int allocation[n];

// Initially no block is assigned to any process


for(i = 0; i < n; i++)
{
allocation[i] = -1;
}

// pick each process and find suitable blocks


// according to its size ad assign to it
for (i = 0; i < n; i++) //here, n -> number of processes
{
for (j = 0; j < m; j++) //here, m -> number of blocks
{
if (blockSize[j] >= processSize[i])
{
// allocating block j to the ith process
allocation[i] = j;

// Reduce available memory in this block.


blockSize[j] -= processSize[i];

break; //go to the next process in the queue


}
}
}

printf("\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++)
{
printf(" %i\t\t\t", i+1);
printf("%i\t\t\t\t", processSize[i]);
if (allocation[i] != -1)
printf("%i", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}
}

// Driver code
int main()
{
int m; //number of blocks in the memory
int n; //number of processes in the input queue
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426};
m = sizeof(blockSize) / sizeof(blockSize[0]);
n = sizeof(processSize) / sizeof(processSize[0]);

firstFit(blockSize, m, processSize, n);

return 0 ;
}
Output:
(EXP-3 : First Fit Memory Allocation)

WORST FIT MEMORY ALLOCATION:


Implementation:
1. Input memory blocks and processes with sizes.
2. Initialize all memory blocks as free.
3. Start by picking each process and find the maximum block size that can be assigned
to current process i.e.,
find max(bockSize[1], blockSize[2],.....blockSize[n]) > processSize[current], if
found then assign it to the current process.
4. If not then leave that process and keep checking
5. the further processes.

Program:
#include <stdio.h>
#include <stdlib.h>

void worstFit(int blockSize[], int m, int processSize[], int n) {


int *allocation = (int *)malloc(n * sizeof(int));
memset(allocation, -1, n * sizeof(int));

for (int i = 0; i < n; i++) {


int wstIdx = -1;
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (wstIdx == -1)
wstIdx = j;
else if (blockSize[wstIdx] < blockSize[j])
wstIdx = j;
}
}

if (wstIdx != -1) {
allocation[i] = wstIdx;
blockSize[wstIdx] -= processSize[i];
}
}

printf("\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++) {
printf(" %d\t\t%d\t\t", i + 1, processSize[i]);
if (allocation[i] != -1)
printf("%d", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}

free(allocation);
}

int main() {
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
worstFit(blockSize, m, processSize, n);
return 0;
}
Output:
(EXP-3 : Worst Fit Memory Allocation)

BEST FIT MEMORY ALLOCATION:


Implementation:
1. Input memory blocks and processes with sizes.
2. Initialize all memory blocks as free.
3. Start by picking each process and find the minimum block size that can be assigned
to current process i.e., find min(bockSize[1], blockSize[2],.....blockSize[n]) >
processSize[current], if found then assign it to the current process.
4. If not then leave that process and keep checking the further processes.

Program:

#include<stdio.h>

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)
bestIdx = j;
else if (blockSize[bestIdx] > blockSize[j])
bestIdx = j;
}
}

if (bestIdx != -1) {

allocation[i] = bestIdx;

blockSize[bestIdx] -= processSize[i];
}
}
printf("\nProcess No.\tProcess Size\tBlock no.\n");
for (int i = 0; i < n; i++) {
printf(" %d\t\t%d\t\t", i+1, processSize[i]);
if (allocation[i] != -1)
printf("%d", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}
}

int main() {
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 42};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);
bestFit(blockSize, m, processSize, n);
return 0;
}

Output:
(EXP-3 : Best Fit Memory Allocation)
EXPERIMENT – 4

AIM: Write a program to implement reader/writer problems using semaphores.


THEORY:
The reader/writer problem is a classic synchronization problem. It deals with concurrent
access to shared resources where multiple processes are involved. The problem can be
defined as follows:
- Multiple readers can simultaneously access a shared resource without any problems.
- Only one writer can access the resource at a time, and no readers can access the resource
while a writer is writing.
Algorithm:
Initialization:
- Initialize the `mutex` semaphore to 1.
- Initialize the `write` semaphore to 1.
- Initialize `read_count` to 0.
Reader Process:
1. Wait on `mutex`.
2. Increment `read_count`.
3. If `read_count` is 1, wait on `write` to prevent writers.
4. Signal `mutex`.
5. Read the data from the shared resource.
6. Wait on `mutex`.
7. Decrement `read_count`.
8. If `read_count` is 0, signal `write` to allow writers.
9. Signal `mutex`.
Writer Process:
1. Wait on `write` to ensure exclusive access for writing.
2. Write data to the shared resource.
3. Signal `write` to release the resource.
PROGRAM
#include <stdio.h>
#include <pthread.h>
int readcount = 0, writecount = 0, sh_var = 5, bsize[5];
pthread_mutex_t x, y, z;
pthread_cond_t rsem, wsem;
void *reader(void *);
void *writer(void *);
void *reader(void *i)
{
printf("\n-------------------------");
printf("\n\n reader-%ld is reading", (long)i);
pthread_mutex_lock(&z);
pthread_mutex_lock(&rsem);
pthread_mutex_lock(&x);
readcount++;
if (readcount == 1)
pthread_mutex_lock(&wsem);
pthread_mutex_unlock(&x);
pthread_mutex_unlock(&rsem);
pthread_mutex_unlock(&z);
printf("\nupdated value: %d", sh_var);
pthread_mutex_lock(&x);
readcount--;
if (readcount == 0)
pthread_mutex_unlock(&wsem);
pthread_mutex_unlock(&x);
}

void *writer(void *i)


{
printf("\n\n writer-%ld is writing", (long)i);
pthread_mutex_lock(&y);
writecount++;
if (writecount == 1)
pthread_mutex_lock(&rsem);
pthread_mutex_unlock(&y);
pthread_mutex_lock(&wsem);
sh_var = sh_var + 5;
pthread_mutex_unlock(&wsem);
pthread_mutex_lock(&y);
writecount--;
if (writecount == 0)
pthread_mutex_unlock(&rsem);
pthread_mutex_unlock(&y);
}
int main()
{
pthread_mutex_init(&x, NULL);
pthread_mutex_init(&y, NULL);
pthread_mutex_init(&z, NULL);
pthread_cond_init(&rsem, NULL);
pthread_cond_init(&wsem, NULL);

pthread_t r[3], w[2];


for (long i = 0; i < 3; i++)
{
pthread_create(&r[i], NULL, reader, (void *)i);
}
for (long i = 0; i < 2; i++)
{
pthread_create(&w[i], NULL, writer, (void *)i);
}

pthread_exit(NULL);
}

OUTPUT:
(EXP-4 : reader/writer problems using semaphores.)
EXPERIMENT – 5

AIM: Write a program to implement Banker’s algorithm for deadlock avoidance.


THEORY:
The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests
for safety by simulating the allocation for the predetermined maximum possible amounts of
all resources, then makes an “s-state” check to test for possible activities, before deciding
whether allocation should be allowed to continue.
Banker’s Algorithm
1. Active:= Running U Blocked;
for k=1…r
New_ request[k]:= Requested_ resources[requesting_ process, k];
2. Simulated_ allocation:= Allocated_ resources;
for k=1…..r //Compute projected allocation state
Simulated_ allocation [requesting _process, k]:= Simulated_ allocation [requesting
_process, k] + New_ request[k];
3. feasible:= true;
for k=1….r // Check whether projected allocation state is feasible
if Total_ resources[k]< Simulated_ total_ alloc [k] then feasible:= false;
4. if feasible= true
then // Check whether projected allocation state is a safe allocation state
while set Active contains a process P1 such that
For all k, Total _resources[k] – Simulated_ total_ alloc[k]>= Max_ need [l ,k]-
Simulated_ allocation[l, k]
Delete Pl from Active;
for k=1…..r
Simulated_ total_ alloc[k]:= Simulated_ total_ alloc[k]- Simulated_ allocation[l, k];
5. If set Active is empty
then // Projected allocation state is a safe allocation state
for k=1….r // Delete the request from pending requests
Requested_ resources[requesting_ process, k]:=0;
for k=1….r // Grant the request
Allocated_ resources[requesting_ process, k]:= Allocated_ resources[requesting_
process, k] + New_ request[k];
Total_ alloc[k]:= Total_ alloc[k] + New_ request[k];
PROGRAM:
// Banker's Algorithm
#include <stdio.h>
int main()
{
// P0, P1, P2, P3, P4 are the Process names here

int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix
{ 2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4
int max[5][3] = { { 7, 5, 3 }, // P0 // MAX Matrix
{ 3, 2, 2 }, // P1
{ 9, 0, 2 }, // P2
{ 2, 2, 2 }, // P3
{ 4, 3, 3 } }; // P4
int avail[3] = { 3, 3, 2 }; // Available Resources
int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {

int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}

if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}

int flag = 1;

for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}

if(flag==1)
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}

return (0);

// This code is contributed by Deep Baldha (CandyZack)


}

OUTPUT:
(EXP-5 : Banker’s algorithm)
EXPERIMENT – 6
AIM: Process Management
Program to implement execv function using C.

THEORY:
execv():
 The `execv()` function is used to replace the current process image with a new
program.
 It loads and runs a new program by specifying its path and command-line arguments.
 The old program's code, data, and stack segments are replaced by the new program.

To implement execv function using C.


PROGRAM:
// child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf ("I am the child process");
printf ("Argument 1: %s\n", argv[1]);
printf ("Argument 2: %s\n", argv[2]);
printf ("Argument 3: %s\n", argv[3]);
}
// parent process
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main (){
printf ("\n\nI am the parent process\n");
char *arg_Ptr[5];
arg_Ptr[0] = " child.c";
arg_Ptr[1] = " \nHello from ";
arg_Ptr[2] = " process 2 ";
arg_Ptr[3] = NULL;
execv("/home/linuxhint/child.bin", arg_Ptr);
}

OUTPUT:
EXPERIMENT – 7

AIM: C program to implement a Shortest Job First scheduling algorithm.


THEORY:

SJF (Shortest Job First) is a scheduling strategy that gives the process with the
quickest CPU burst time to the CPU first. As this technique is non-preemptive, once a
process has begun to run, it cannot be stopped until it has finished. The SJF scheduling
method is ideal since it reduces the average waiting time for a set of processes.

In this blog post, we will learn how to implement the SJF scheduling algorithm in C
programming language. We will start by discussing the algorithm and its working, followed
by the implementation details in C. We will also provide a sample code with syntax, example,
and output to help you understand the concept better.

Algorithm:

The SJF scheduling algorithm works as follows:

1. Find the process with the shortest CPU burst time.


2. Execute the process until completion.
3. Repeat steps 1 and 2 until all processes are executed.

Steps:
1. We first take input from the user for the number of processes, arrival time,
and burst time of each process.
2. We create an array of structures to store the information about each process.
3. We use the qsort() function to sort the processes based on their burst time.
4. We calculate the waiting time of each process using the SJF scheduling algorithm.
5. We calculate the average waiting time and average turnaround time of all
processes.
6. Finally, we print the results in tabular form.

Program:
1. struct Process {
2. int arrival_time;
3. int burst_time;
4. int waiting_time;
5. };
6.
7. int compare(const void *a, const void *b) {
8. struct Process *p1 = (struct Process *)a;
9. struct Process *p2 = (struct Process *)b;
10. return p1->burst_time - p2->burst_time;
11. }
12.
13. int main() {
14. int n, i, j;
15. float avg_waiting_time = 0, avg_turnaround_time = 0;
16. printf("Enter the number of processes: ");
17. scanf("%d", &n);
18. struct Process processes[n];
19. for (i = 0; i< n; i++) {
20. printf("Enter arrival time and burst time of process %d: ", i+1);
21. scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);
22. }
23. qsort(processes, n, sizeof(struct Process), compare);
24. processes[0].waiting_time = 0;
25. for (i = 1; i< n; i++) {
26. processes[i].waiting_time = 0;
27. for (j = 0; j <i; j++)
28. {
29.
30. processes[i].waiting_time += processes[j].burst_time;
31.
32. }
33.
34. avg_waiting_time += processes[i].waiting_time;
35.
36. }
37.
38. avg_waiting_time /= n;
39.
40. for (i = 0; i< n; i++) {
41.
42. avg_turnaround_time += processes[i].burst_time + processes[i].waiting_time;
43.
44. }
45.
46. avg_turnaround_time /= n;
47.
48. printf("\nProcess\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\n");
49.
50. for (i = 0; i< n; i++) {
51.
52. printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n", i+1, processes[i].arrival_time, processes[i].burst_time, processes[i].w
aiting_time, processes[i].burst_time+processes[i].waiting_time);
53.
54. }
55.
56. printf("\nAverage Waiting Time: %f\n", avg_waiting_time);
57.
58. printf("Average Turnaround Time: %f\n", avg_turnaround_time);
59.
60. return 0;
61.
62. }

Output:
EXPERIMENT – 8

AIM: C program to implement a priority scheduling algorithm.

THEORY:

Priority scheduling is a CPU scheduling algorithm where processes are assigned priorities,
and the process with the highest priority is selected for execution. In priority scheduling, the
scheduler chooses the process with the highest priority number from the ready queue and
allocates the CPU to that process. The priority of a process is usually determined by its
importance, the amount of CPU time it needs, or its deadline.

Priority scheduling can be divided into two types: preemptive and non-preemptive. In
preemptive priority scheduling, the currently running process may be interrupted by a higher
priority process, while in non-preemptive priority scheduling, once a process is assigned the
CPU, it will continue to execute until it finishes or is blocked.

Priority scheduling is a widely used algorithm for CPU scheduling in OS. It assigns
priorities to different processes and chooses the process with the highest priority for
execution. In this blog post, we provided a sample program in C for priority scheduling that
sorts the processes based on their priority and calculates the waiting time and turnaround time
for each process.

Program:
1. #include<stdio.h>
2. #include<stdlib.h>
3.
4. struct process {
5. int process_id;
6. int burst_time;
7. int priority;
8. int waiting_time;
9. int turnaround_time;
10. };
11.
12. void find_waiting_time(struct process[], int, int[]);
13. void find_turnaround_time(struct process[], int, int[], int[]);
14.
15. void find_average_time(struct process[], int);
16.
17. void priority_scheduling(struct process[], int);
18.
19. int main()
20. {
21. int n, i;
22. struct process proc[10];
23.
24. printf("Enter the number of processes: ");
25. scanf("%d", &n);
26.
27. for(i = 0; i< n; i++)
28. {
29. printf("\nEnter the process ID: ");
30. scanf("%d", &proc[i].process_id);
31.
32. printf("Enter the burst time: ");
33. scanf("%d", &proc[i].burst_time);
34.
35. printf("Enter the priority: ");
36. scanf("%d", &proc[i].priority);
37. }
38.
39. priority_scheduling(proc, n);
40. return 0;
41. }
42.
43. void find_waiting_time(struct process proc[], int n, int wt[])
44. {
45. int i;
46. wt[0] = 0;
47.
48. for(i = 1; i< n; i++)
49. {
50. wt[i] = proc[i - 1].burst_time + wt[i - 1];
51. }
52. }
53.
54. void find_turnaround_time(struct process proc[], int n, int wt[], int tat[])
55. {
56. int i;
57. for(i = 0; i< n; i++)
58. {
59. tat[i] = proc[i].burst_time + wt[i];
60. }
61. }
62.
63. void find_average_time(struct process proc[], int n)
64. {
65. int wt[10], tat[10], total_wt = 0, total_tat = 0, i;
66.
67. find_waiting_time(proc, n, wt);
68. find_turnaround_time(proc, n, wt, tat);
69.
70. printf("\nProcess ID\tBurst Time\tPriority\tWaiting Time\tTurnaround Time");
71.
72. for(i = 0; i< n; i++)
73. {
74. total_wt = total_wt + wt[i];
75. total_tat = total_tat + tat[i];
76. printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d", proc[i].process_id, proc[i].burst_time, proc[i].priority, wt[i], tat[i]);
77. }
78.
79. printf("\n\nAverage Waiting Time = %f", (float)total_wtotal_wt/n);
80. printf("\nAverage Turnaround Time = %f\n", (float)total_tat/n);
81. }
82.
83. void priority_scheduling(struct process proc[], int n)
84. {
85. int i, j, pos;
86. struct process temp;
87. for(i = 0; i< n; i++)
88. {
89. pos = i;
90. for(j = i + 1; j < n; j++)
91. {
92. if(proc[j].priority< proc[pos].priority)
93. pos = j;
94. }
95.
96. temp = proc[i];
97. proc[i] = proc[pos];
98. proc[pos] = temp;
99. }
100.
101. find_average_time(proc, n);
102. }

Output:

You might also like