0% found this document useful (0 votes)
57 views17 pages

Ass 3

The document discusses different CPU scheduling algorithms like FCFS, SJF, RR and priority scheduling. It provides code implementations for each algorithm and explains how to simulate them. The code shows how to calculate waiting times, turnaround times and average metrics for each algorithm.

Uploaded by

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

Ass 3

The document discusses different CPU scheduling algorithms like FCFS, SJF, RR and priority scheduling. It provides code implementations for each algorithm and explains how to simulate them. The code shows how to calculate waiting times, turnaround times and average metrics for each algorithm.

Uploaded by

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

Operating System – Assignment -3

{ Submitted by :Jasjot Singh SID:


22103039
Lab Group : CSE – G1 }
Q1) Implement a simple producer consumer problem using shared memory or message
queues. Create two separate programs :one for the producer and one for the consumer. The
producer should generate data items and store them in a shared memory segment or send
them through a message queue. The consumer should retrieve data items from the shared
memory segment or message queue and process them

Soln->
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
pid_t child_pid;

// Create a child process


child_pid = fork();

if (child_pid < 0) {
// Fork failed
fprintf(stderr, "Fork failed\n");
return 1;
} else if (child_pid == 0) {
// Child process
printf("Child process PID: %d\n", getpid());
// Child process terminates
exit(0);
} else {
// Parent process
printf("Parent process PID: %d\n", getpid());
printf("Waiting for child process to complete...\n");
// Wait for the child process to complete
wait(NULL);
printf("Child process has completed.\n");
}
return 0;
}
Q2) Write a C program to demonstrate the concept of process synchronization
using semaphores or mutex locks. Implement a scenario where multiple processes
are trying to access a shared resource. Use semaphores or mutex locks to ensure
that only one process can access the shared resource at a time.

Soln- >
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 5

// Global shared resource


int shared_resource = 0;

// Mutex lock declaration


pthread_mutex_t lock;

// Function to represent the critical section where the shared resource is accessed
void *access_shared_resource(void *thread_id) {
long tid = (long)thread_id;

// Lock the mutex before accessing the shared resource


pthread_mutex_lock(&lock);

// Critical section: Accessing and modifying the shared resource shared_resource+


+;
printf("Thread %ld accessed shared resource. Shared resource value: %d\n", tid, shared_resource);

// Unlock the mutex after accessing the shared resource


pthread_mutex_unlock(&lock);

pthread_exit(NULL);
}

int main() {
pthread_t threads[NUM_THREADS];
int rc;
long t;

// Initialize mutex lock


pthread_mutex_init(&lock, NULL);

// Create multiple threads


for (t = 0; t < NUM_THREADS; t++) {
printf("Creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, access_shared_resource, (void *)t);
if (rc) {
printf("ERROR: return code from pthread_create() is %d\n",
rc); exit(-1);
}
}
// Wait for all threads to complete
for (t = 0; t < NUM_THREADS; t++)
{
pthread_join(threads[t], NULL);
}

// Destroy mutex lock


pthread_mutex_destroy(&lock);

return 0;
}

Q3) Implement a simple producer consumer problem using shared memory or message queues.
Create two separate programs :one for the producer and one for the consumer. The producer
should generate data items and store them in a shared memory segment or send them through
a message queue. The consumer should retrieve data items from the shared memory segment
or message queue and process them

Soln->

(Producer Code)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

#define SHMSZ 1024 // Size of shared memory segment


int main()
{ int
shmid;
key_t key;
char *shm, *data;

// Generate a unique key for the shared memory


segment key = ftok(".", 'X');
if (key == -1) {
perror("ftok");
exit(1);
}

// Create the shared memory segment


if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0)
{ perror("shmget");
exit(1);
}

// Attach the shared memory segment to the producer's address space


shm = shmat(shmid, NULL, 0);
if (shm == (char *) -1) {
perror("shmat");
exit(1);
}

data = shm;

// Produce data items


for (char c = 'A'; c <'Z'; c++) {
*data++ = c;
sleep(1); // Simulate data generation time
}

// Mark end of data with null character


*data = '\0';

// Print out the contents of the shared memory segment


printf("Contents of shared memory segment:\n%s\n", shm);

// Detach the shared memory segment


if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}

return 0;
}
(Consumer Code)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHMSZ 1024 // Size of shared memory segment

int main() {
int shmid;
key_t key;
char *shm, *data;

// Generate the same key used by the producer to access the shared memory segment
key = ftok(".", 'X');

// Locate the existing shared memory segment


if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
perror("shmget");
exit(1);
}

// Attach the shared memory segment to the consumer's address space


if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}

data = shm;

// Consume data items


while (*data != '\0') {
printf("%c ", *data++);
fflush(stdout); // Flush output buffer
sleep(1); // Simulate data processing time
}

printf("\n");

// Detach the shared memory segment


shmdt(shm);

// Remove the shared memory segment


shmctl(shmid, IPC_RMID, NULL);

return 0;
}

Q4) Simulate different scheduling algorithms such as first come first serve(FCFS), Shortest job
first (SJF) , round robin (RR) and priority scheduling (PSC)

Soln)

First Come First Serve(FCFS)


#include <stdio.h>

void fcfs(int bt[], int n) {


int wt[n], tat[n], total_wt = 0, total_tat = 0;

wt[0] = 0; // Waiting time for the first process is 0

// Calculate waiting time for each process


for (int i = 1; i < n; i++) {
wt[i] = wt[i - 1] + bt[i - 1];
total_wt += wt[i];
}

// Calculate turnaround time for each process


for (int i = 0; i < n; i++) {
tat[i] = bt[i] + wt[i];
total_tat += tat[i];
}

// Display results
printf("Process\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", i + 1, bt[i], wt[i], tat[i]);
}

// Calculate average waiting time and average turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n", avg_tat);
}

int main() {
int bt[] = {10, 5, 8, 12};
int n = sizeof(bt) / sizeof(bt[0]);
fcfs(bt, n);
return 0;
}

Shortest Job First (SJF)


#include <stdio.h>

void sjf(int bt[], int n) {


int wt[n], tat[n], total_wt = 0, total_tat = 0;
int temp[n], p[n];

// Copy burst times to temp array


for (int i = 0; i < n; i++) {
temp[i] = bt[i];
p[i] = i;
}

// Sort burst times in ascending order using bubble


sort for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (temp[j] > temp[j + 1]) {
int t = temp[j];
temp[j] = temp[j + 1];
temp[j + 1] = t;

t = p[j];
p[j] = p[j + 1];
p[j + 1] = t;
}
}
}

// Calculate waiting time for each process


wt[0] = 0;
for (int i = 1; i < n; i++) {
wt[i] = wt[i - 1] + temp[i - 1];
total_wt += wt[i];
}

// Calculate turnaround time for each process


for (int i = 0; i < n; i++) {
tat[i] = temp[i] + wt[i];
total_tat += tat[i];
}

// Display results
printf("Process\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", p[i] + 1, bt[p[i]], wt[i], tat[i]);
}

// Calculate average waiting time and average turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n", avg_tat);
}

int main() {
int bt[] = {6, 3, 8, 7, 4};
int n = sizeof(bt) / sizeof(bt[0]);
sjf(bt, n);
return 0;
}

Round Robin (RR)


#include <stdio.h>

#define MAX_PROCESS 10

// Structure to represent a process


struct Process {
int pid; // Process ID
int bt; // Burst Time
int priority; // Priority
int rt; // Remaining Time
};

// Function to perform Round Robin scheduling


void roundRobin(struct Process processes[], int n, int quantum)
{ int remainingTime[MAX_PROCESS];
int t = 0; // Current time
float total_wt = 0, total_tat = 0;

// Initialize remaining time for each process


for (int i = 0; i < n; i++) {
remainingTime[i] = processes[i].bt;
}

// Continue scheduling until all processes are done


while (1) {
int done = 1; // Assume all processes are done

// Traverse each process one by one


for (int i = 0; i < n; i++) {
// If burst time is greater than 0, process is not yet finished
if (remainingTime[i] > 0) {
done = 0; // Mark as unfinished

// If burst time is greater than quantum, execute for quantum time


if (remainingTime[i] > quantum) {
t += quantum;
remainingTime[i] -= quantum;
}
// If burst time is less than or equal to quantum, execute for remaining time
else {
t += remainingTime[i];
processes[i].rt = t;
remainingTime[i] = 0;
}
}
}

// If all processes are done, break the loop


if (done == 1)
break;
}

// Calculate waiting time and turnaround time for each process


for (int i = 0; i < n; i++) {
processes[i].rt -=
processes[i].bt; total_wt +=
processes[i].rt;
total_tat += processes[i].bt + processes[i].rt;
}

// Print results
printf("Process\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t\t%d\n", processes[i].pid, processes[i].rt, processes[i].bt + processes[i].rt);
}

// Calculate and print average waiting time and turnaround time


printf("Average Waiting Time: %.2f\n", total_wt / n);
printf("Average Turnaround Time: %.2f\n", total_tat / n);
}

int main() {
int n, quantum;
printf("Enter the number of processes: ");
scanf("%d", &n);

struct Process processes[MAX_PROCESS];


printf("Enter burst time and priority for each process:\
n"); for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Process %d: ", i + 1);
scanf("%d %d", &processes[i].bt, &processes[i].priority);
}

printf("Enter the time quantum for Round Robin: ");


scanf("%d", &quantum);

roundRobin(processes, n, quantum);

return 0;
}

Priority Scheduling (PSC)


#include <stdio.h>

#define MAX_PROCESS 10

// Structure to represent a process


struct Process {
int pid; // Process ID
int bt; // Burst Time
int priority; // Priority
};

// Function to perform Priority Scheduling


void priorityScheduling(struct Process processes[], int n) {
// Sort processes based on priority (higher priority goes first)
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].priority < processes[j + 1].priority)
{ struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}

// Calculate waiting time and turnaround time for each process


int wt[MAX_PROCESS], tat[MAX_PROCESS], total_wt = 0, total_tat = 0;
wt[0] = 0; // Waiting time for the first process is 0

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


wt[i] = wt[i - 1] + processes[i - 1].bt;
total_wt += wt[i];
}

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


tat[i] = processes[i].bt + wt[i];
total_tat += tat[i];
}

// Print results
printf("Process\tBurst Time\tPriority\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t\t%d\t\t%d\t\t%d\n", processes[i].pid, processes[i].bt, processes[i].priority, wt[i], tat[i]);
}

// Calculate and print average waiting time and turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n", avg_tat);
}

int main()
{ int n;
printf("Enter the number of processes: ");
scanf("%d", &n);

struct Process processes[MAX_PROCESS];

printf("Enter burst time and priority for each process:\


n"); for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Process %d: ", i + 1);
scanf("%d %d", &processes[i].bt, &processes[i].priority);
}

priorityScheduling(processes, n);

return 0;
}
Q5) Write a program to create multiple processes with different CPU burst times and priorities.
Implement each scheduling algorithm separately and compare their performance based on
metrics such as average waiting time , turn around time etc

Soln->
#include <stdio.h>
#include <stdlib.h>

#define MAX_PROCESS 10

// Structure to represent a process


struct Process {
int pid; // Process ID
int bt; // Burst Time
int priority; // Priority
};

// Function to perform First Come First Serve (FCFS) Scheduling


void fcfs(struct Process processes[], int n) {
int wt[MAX_PROCESS], tat[MAX_PROCESS], total_wt = 0, total_tat = 0;
wt[0] = 0; // Waiting time for the first process is 0

// Calculate waiting time for each process


for (int i = 1; i < n; i++) {
wt[i] = wt[i - 1] + processes[i - 1].bt;
total_wt += wt[i];
}

// Calculate turnaround time for each process


for (int i = 0; i < n; i++) {
tat[i] = processes[i].bt + wt[i];
total_tat += tat[i];
}

// Print results
printf("First Come First Serve (FCFS) Scheduling:\n");
printf("Process\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].pid, processes[i].bt, wt[i], tat[i]);
}

// Calculate and print average waiting time and turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n\n", avg_tat);
}

// Function to perform Shortest Job First (SJF) Scheduling


void sjf(struct Process processes[], int n) {
// Sort processes based on burst time (shorter burst time goes first)
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].bt > processes[j + 1].bt)
{ struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}

// Calculate waiting time and turnaround time for each process


int wt[MAX_PROCESS], tat[MAX_PROCESS], total_wt = 0, total_tat = 0;
wt[0] = 0; // Waiting time for the first process is 0

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


wt[i] = wt[i - 1] + processes[i - 1].bt;
total_wt += wt[i];
}

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


tat[i] = processes[i].bt + wt[i];
total_tat += tat[i];
}

// Print results
printf("Shortest Job First (SJF) Scheduling:\n");
printf("Process\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].pid, processes[i].bt, wt[i], tat[i]);
}

// Calculate and print average waiting time and turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n\n", avg_tat);
}

// Function to perform Priority Scheduling


void priorityScheduling(struct Process processes[], int n) {
// Sort processes based on priority (higher priority goes first)
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].priority < processes[j + 1].priority) {
struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
int wt[MAX_PROCESS], tat[MAX_PROCESS], total_wt = 0, total_tat = 0;
wt[0] = 0; // Waiting time for the first process is 0

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


wt[i] = wt[i - 1] + processes[i - 1].bt;
total_wt += wt[i];
}

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


tat[i] = processes[i].bt + wt[i];
total_tat += tat[i];
}

// Print results
printf("Priority Scheduling:\n");
printf("Process\tBurst Time\tPriority\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t%d\t\t%d\t\t%d\t\t%d\n", processes[i].pid, processes[i].bt, processes[i].priority, wt[i], tat[i]);
}

// Calculate and print average waiting time and turnaround time


float avg_wt = (float)total_wt / n;
float avg_tat = (float)total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n\n", avg_tat);
}

// Function to perform Round Robin (RR) Scheduling


void roundRobin(struct Process processes[], int n, int quantum) {
// Create an array to store remaining burst time for each process
int remainingTime[MAX_PROCESS];
for (int i = 0; i < n; i++) {
remainingTime[i] = processes[i].bt;
}

int t = 0; // Current time


int wt[MAX_PROCESS] = {0}; // Waiting time for each process
int tat[MAX_PROCESS] = {0}; // Turnaround time for each process

// Continue scheduling until all processes are done


while (1) {
int done = 1; // Flag to check if all processes are done

// Traverse each process one by one


for (int i = 0; i < n; i++) {
// If remaining burst time for the process is greater than 0, it means it's not done
yet if (remainingTime[i] > 0) {
done = 0; // Mark as not done

// If remaining burst time is greater than quantum, execute for quantum


time if (remainingTime[i] > quantum) {
t += quantum;
remainingTime[i] -= quantum;
} else { // If remaining burst time is less than or equal to quantum, execute for remaining
time t += remainingTime[i];
wt[i] = t - processes[i].bt;
remainingTime[i] = 0;
}
}
}

// If all processes are done, break the loop


if (done == 1)
break;
}

// Calculate turnaround time for each process


for (int i = 0; i < n; i++) {
tat[i] = processes[i].bt + wt[i];
}

// Print results
printf("Round Robin (RR) Scheduling with Quantum %d:\n", quantum);
printf("Process\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].pid, processes[i].bt, wt[i], tat[i]);
}

// Calculate and print average waiting time and turnaround time


float total_wt = 0, total_tat = 0;
for (int i = 0; i < n; i++)
{ total_wt += wt[i];
total_tat += tat[i];
}
float avg_wt = total_wt / n;
float avg_tat = total_tat / n;
printf("Average Waiting Time: %.2f\n", avg_wt);
printf("Average Turnaround Time: %.2f\n\n", avg_tat);
}

int main() {
int n, quantum;
struct Process processes[MAX_PROCESS];

// Input number of processes


printf("Enter the number of processes: ");
scanf("%d", &n);

// Input burst time and priority for each process


printf("Enter burst time and priority for each process:\
n"); for (int i = 0; i < n; i++) {
processes[i].pid = i + 1;
printf("Process %d: ", i + 1);
scanf("%d %d", &processes[i].bt, &processes[i].priority);
}

// Perform FCFS Scheduling


fcfs(processes, n);

// Perform SJF Scheduling


sjf(processes, n);

// Perform Priority Scheduling

// Input time quantum for Round Robin Scheduling


printf("Enter the time quantum for Round Robin: ");
scanf("%d", &quantum);

// Perform Round Robin Scheduling


roundRobin(processes, n, quantum);
priorityScheduling(processes, n);
return 0;
}

// Calculate waiting time and turnaround time for each process

You might also like