You are on page 1of 59

OPERATING SYSTEM LAB

ETCS 352

Submitted To: Submitted by:


Mr. Navdeep Bohra Name: Tanya
Chaudhary

Serial No: 31
Enrolment No:06715002717
Class: CSE-2(B)

Maharaja Surajmal Institute of Technology,


C-4 Janak Puri, New Delhi 110058
1
Experiment - 1

Aim:

Write a program to implement CPU scheduling for first come first serve.

Theory:

First in, first out (FIFO), also known as first come, first served (FCFS), is the
simplest scheduling algorithm. FIFO simply queues processes in the order that
they arrive in the ready queue. In this, the process that comes first will be
executed first and next process starts only after the previous gets fully executed.

It's easy to understand and implement programmatically, using a Queue data


structure, where a new process enters through the tail of the queue, and the
scheduler selects process from the head of the queue.

● Turn Around Time: Time Difference between completion time and arrival
time. Turn Around Time = Completion Time – Arrival Time
● Waiting Time (W.T): Time Difference between turn around time and burst
time.
Waiting Time = Turn Around Time – Burst Time

Program Code:
#include<bits/stdc++.h>
using namespace std;
//class to store each process details
class gObject{
public:
int start;
int id;
int end;
int wt;
int tat;

2
int bt;
int at;
};
int main(){
//input
int n,cur_time = 0;
cout<<"Enter no of process : ";
queue<gObject *>gantt;
vector<gObject *>list;
cin>>n;
for(int j =0 ; j < n;j++){
gObject *temp = new gObject();
cin>>temp->id>>temp->bt>>temp->at;
temp->start = cur_time;
temp->wt = cur_time - temp->at;
temp->tat = temp->wt + temp->bt;
cur_time += temp->bt;
temp->end = cur_time;
//Inset each process into queue on the basis of fcfs
gantt.push(temp);
list.push_back(temp);
}
cout<<"\nGantt Chart\n";
while(gantt.size() > 0){
cout<<gantt.front()->start<<" |P"<<gantt.front()->id<<"| ";
if(gantt.size() == 1){
cout<<gantt.front()->end;
}
gantt.pop();
}
float avg_wt = 0,avg_tat = 0;

3
cout<<"\nTable "<<endl;
cout<<"Process BT\t AT\t WT \t TAT"<<endl;
for(int j = 0; j < list.size();j++){
avg_wt += list[j]->wt;
avg_tat += list[j]->tat;
cout<<"P"<<list[j]->id<<" \t"<<list[j]->bt<<"\t"<<list[j]->at<<"\t"<<list[j]
- >wt<<"\t"<<list[j]->tat<<endl;
}
cout<<"\nAverage wating time : "<<avg_wt/n;
cout<<"\nAverage turn around time : "<<avg_tat/n;
return 0;
}
Output:

4
5
Experiment – 2

Aim:

a. Write a program to implement CPU scheduling for shortest job first.


b. Write a program to implement CPU scheduling for shortest time remaining
first.

a.
Theory:
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 is a non-
preemptive algorithm.

Advantages:

● Shortest Job first has the advantage of having a minimum average


waiting time among all scheduling algorithms.
● It is a Greedy Algorithm.

Disadvantages:

● It is practically infeasible as Operating System may not know burst


time 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.

Program Code:

#include<bits/stdc++.h>

using namespace std;

class process{

6
public :

int id; int bt;

int at;int wt;

int bt_start; int last_seen;

};

struct mH{

bool operator()(process const *p1,process const *p2){

if(p1->at == p2->at){

return true;

return p1->at < p2->at;

};

struct minpq{

bool operator()(process const *p1,process const *p2){

return p1->bt > p2->bt;

};

class gObject{

public:

int start;

int id;

int end;

7
};

int main(){

int n;

cout<<"Enter no of process : ";

vector<process *>list;

vector<gObject *>gantt;

priority_queue<process *,vector<process *>,minpq>pq;

cin>>n;

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

process * temp = new process();

cin>>temp->id>>temp->bt>>temp->at;

temp->bt_start = temp->bt;

temp->last_seen = temp->at;

list.push_back(temp);

sort(list.begin(),list.end(),mH());

process *prev_process = nullptr;

int i = 0,prev_time = 0,cur_time = 0;

int process_solved = 0;

while(process_solved < n){

pq = priority_queue<process*,vector<process*>,minpq>();

for(int j=0;j < list.size() && list[j]->at <= cur_time;j++){

if(list[j]->bt != 0){

8
pq.push(list[j]);

pq.top()->bt = 0;

pq.top()->wt = cur_time - pq.top()->last_seen;

process_solved++;

gObject *temp = new gObject();

temp->id = pq.top()->id;

temp->start = cur_time;

cur_time += pq.top()->bt_start;

temp->end = cur_time;

gantt.push_back(temp);

cout<<"Gantt Chart"<<endl;

for(int j = 0; j < gantt.size();j++){

cout<<gantt[j]->start<<" |P"<<gantt[j]->id<<"| ";

if(j == gantt.size() - 1){

cout<<gantt[j]->end;

float avg_tat = 0,avg_wt = 0;

cout<<"\nTable "<<endl;

cout<<"Process BT\t AT\t WT \t TAT"<<endl;

9
for(int j = 0; j < list.size();j++){

int tat = list[j]->wt + list[j]->bt_start;

avg_tat += tat;

avg_wt += list[j]->wt;

cout<<"P"<<list[j]->id<<" \t"<<list[j]->bt_start<<"\t"<<list[j]->at<<"\t"<<list[j]
->wt<<"\t"<<tat<<endl;

cout<<"\nAverage wating time : "<<avg_wt/n;

cout<<"\nAverage turn around time : "<<avg_tat/n;

return 0;

Output:

10
b.

Theory:

SRTF, Which Stands for Shortest Remaining Time First is a scheduling algorithm
used in Operating Systems, which can also be called as the preemptive version of
the SJF scheduling algorithm. The process which has the least processing time
remaining is executed first. In SRTF, processor is allocated to the job closest to
completion.

In SRTF, the execution of the process can be stopped after certain amount of
time. At the arrival of every process, the short-term scheduler schedules the
process with the least remaining burst time among the list of available processes
and the running process.

Advantages:

SRTF algorithm makes the processing of the jobs faster than SJN
algorithm, given its overhead charges are not counted.

Disadvantages:

The context switch is done a lot more times in SRTF than in SJN, and
consumes CPU’s valuable time for processing. This adds up to its
processing time and diminishes its advantage of fast processing.

Program Code:

#include<bits/stdc++.h>

using namespace std;

class process{

public :

int id;int bt;

int at;int wt;

11
int bt_start;

int last_seen;

};

struct mH{

bool operator()(process const *p1,process const *p2){

if(p1->at == p2->at){

return true;

return p1->at < p2->at;

};

struct minpq{

bool operator()(process const *p1,process const *p2){

return p1->bt > p2->bt;

};

class gObject{

public:

int start; int id; int end;

};

int main(){

int n;

cout<<"Enter no of process : ";

12
vector<process *>list;

vector<gObject *>gantt;

priority_queue<process *,vector<process *>,minpq>pq;

cin>>n;

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

process * temp = new process();

cin>>temp->id>>temp->bt>>temp->at;

temp->bt_start = temp->bt;

temp->last_seen = temp->at;

list.push_back(temp);

sort(list.begin(),list.end(),mH());

process *prev_process = nullptr;

int i = 0,prev_time = 0,cur_time = 0;

while(i < list.size()){

pq = priority_queue<process*,vector<process *>,minpq>();

while(i < list.size()-1 && list[i]->at == list[i+1]->at){

i++;

cur_time = list[i]->at;

int time_alloted;

gObject *temp = new gObject();

if(i > 0){

13
temp->end = cur_time;

temp->start = prev_time;

temp->id = prev_process->id;

time_alloted = cur_time - prev_time;

if(time_alloted > prev_process->bt){

prev_time = prev_time + prev_process->bt;

prev_process->bt = 0;

}else{

prev_process->bt = prev_process->bt - time_alloted;

prev_time = cur_time;

prev_process->last_seen = cur_time;

if(gantt.size() == 0 || prev_process->id != gantt[gantt.size() - 1]->id){

gantt.push_back(temp);

}else{

gantt[gantt.size() - 1]->end = temp->end;

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

if(list[j]->bt != 0){

pq.push(list[j]);

14
prev_process = pq.top();

prev_process->wt += cur_time - prev_process->last_seen;

if(i == 0){

i++;

prev_time = cur_time;

continue;

i++;

while(pq.size() > 0){

gObject *temp = new gObject();

prev_time = cur_time;

pq.top()->wt += cur_time - pq.top()->last_seen;

cur_time += pq.top()->bt;

temp->start = prev_time;

temp->id = pq.top()->id;

temp->end = cur_time;

pq.top()->last_seen = cur_time;

pq.top()->bt = 0;

if(pq.top()->id != gantt[gantt.size() - 1]->id){

gantt.push_back(temp);

}else{

15
gantt[gantt.size() - 1]->end = temp->end;

pq.pop();

cout<<"Gantt Chart"<<endl;

for(int j = 0; j < gantt.size();j++){

cout<<gantt[j]->start<<" |P"<<gantt[j]->id<<"| ";

if(j == gantt.size() - 1){

cout<<gantt[j]->end;

cout<<"\nTable "<<endl;

float avg_wt = 0,avg_tat = 0;

cout<<"Process BT\t AT\t WT \t TAT"<<endl;

for(int j = 0; j < list.size();j++){

avg_wt += list[j]->wt;

int tat = list[j]->wt + list[j]->bt_start;

avg_tat += tat;

cout<<"P"<<list[j]->id<<" \t"<<list[j]->bt_start<<

"\t"<<list[j]->at<<"\t"<<list[j]->wt<<"\t"<<tat<<endl;

cout<<"\nAverage wating time : "<<avg_wt/n;

cout<<"\nAverage turn around time : "<<avg_tat/n;

16
return 0;

Output:

17
Experiment – 3

Aim:

Write a program to implement CPU scheduling for priority basis.

Theory:

Priority scheduling is one of the most common scheduling algorithms in batch


systems. Each process is assigned a priority. Process with the highest priority is
to be executed first and so on. Processes with the same priority are executed on
first come first served basis. Priority can be decided based on memory
requirements, time requirements or any other resource requirement.

Example:

Process Details:

Gantt Chart:

18
Table:

Program:

import java.util.*;

class process{

public int id,bt;

public int at,start;

public int end,tat;

public int pr, wt;

public class pract{

public static void main(String[] args) {

Scanner s = new Scanner(System.in);

System.out.println("Enter no of process : ");

int n = s.nextInt();

System.out.println("Enter ID\t BT\t AT\t PR");

ArrayList<process> lop = new ArrayList<>();

ArrayList<process> gt = new ArrayList<>();

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

process np = new process();

np.id = s.nextInt();

np.bt = s.nextInt();

np.at = s.nextInt();

np.pr = s.nextInt();

lop.add(np);

Collections.sort(lop,new Comparator<process>(){

public int compare(process a,process b){

return a.at - b.at;

});

int process_solved = 0;

int cur_time = 0;

float avg_tat = 0,avg_wt = 0;

while(process_solved < n){

PriorityQueue<process>pq = new PriorityQueue<>

(new Comparator<process>() {

public int compare(process a,process b){

return a.pr - b.pr;

});

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

if(lop.get(i).at <= cur_time && lop.get(i).bt != 0){

pq.add(lop.get(i));

process present_ = pq.peek();

present_.start = cur_time;

present_.wt = cur_time - present_.at;

present_.tat = present_.bt;

cur_time += present_.bt;

present_.bt = 0;

present_.end = cur_time;

present_.tat += present_.wt;

avg_tat += (float)(present_.tat/n);

avg_wt += (float)(present_.wt/n);

gt.add(present_);

process_solved++;

System.out.print("0");

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

System.out.print(" - [ "+gt.get(i).id +" ] - " + gt.get(i).end);

System.out.println("Table : \nId\tAT\tPR\tBT\tTAT\tWT");

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

System.out.println(gt.get(i).id+"\t"+gt.get(i).at+"\t"+gt.get(i).pr+

"\t"+gt.get(i).bt+"\t"+gt.get(i).tat+"\t"+gt.get(i).wt);

System.out.println("Average Wating Time : " + avg_wt);

System.out.println("Average Turn Around Time : " + avg_tat);

s.close();

Output:

22
Experiment – 4

Aim:

Write a program to implement CPU scheduling for Robin Round.

Theory:

Round Robin is a CPU scheduling algorithm where each process is assigned a


fixed time slot in a cyclic way. Round Robin is the preemptive process
scheduling algorithm. Each process is provided a fix time to execute, it is called
a quantum. Once a process is executed for a given time period, it is preempted
and other process executes for a given time period. Context switching is used to
save states of preempted processes.

Example:

Process Details:

Gantt Chart:

23
Table:

Program:

import java.util.*;

class process {

public int pid;

public int bt;

public int at;

public int wt;

public int start;

public int end;

public int tat;

public int total;

public class pract{

public static void main(String[] args) {

Scanner scn = new Scanner(System.in);

System.out.println("Enter no of process : ");

24
int totalP = scn.nextInt();

System.out.println("Id\t At\t BT\t TAT\t WT");

ArrayList<process> pp= new ArrayList<>();

ArrayDeque <process> status = new ArrayDeque<>();

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

process temp = new process();

temp.pid = scn.nextInt();

temp.at = scn.nextInt();

temp.bt = scn.nextInt();

temp.total = temp.bt;

pp.add(temp);

int quantum = 3;

Collections.sort(pp,new Comparator<process>(){

public int compare(process a,process b){

return a.at - b.at;

});

int time = 0,solved = 0;

int ptime = -1;

ArrayList<process> gtid = new ArrayList<>();

ArrayList<Integer> gtstart = new ArrayList<>();

ArrayList<Integer> gtend = new ArrayList<>();

25
System.out.print("Gantt Chart\n " + 0);

while(solved < totalP){

for(int i = totalP-1; i >= 0;i--){

if(pp.get(i).at <= time && pp.get(i).at > ptime && pp.get(i).bt > 0){

status.addFirst(pp.get(i));

process rem = status.pollFirst();

gtstart.add(time);

if(rem.bt > quantum){

rem.wt += (time - rem.start);

rem.bt -= quantum;

ptime = time;

time += quantum;

rem.start = time;

status.addLast(rem);

}else{

rem.wt += (time - rem.start);

ptime = time;

time += rem.bt;

rem.bt = 0;

rem.wt -= rem.at;

rem.tat = rem.wt + rem.total;

26
solved ++;

System.out.print("-[ P" + rem.pid + " ]-" + time);

gtid.add(rem);

float avgtat = 0;

float avgbt = 0;

System.out.println("\nTable: \nId\t At\t BT\t TAT\t WT");

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

System.out.println(gtid.get(i).pid + "\t" + gtid.get(i).at + "\t" +

gtid.get(i).total + "\t" + gtid.get(i).tat + "\t" +gtid.get(i).wt

);

avgtat += (float)(gtid.get(i).tat);

avgbt += (float)(gtid.get(i).wt);

System.out.println("Average total turn around time : " + avgtat/totalP);

System.out.println("Average waiting time : " + avgbt/totalP);

Output:

27
28
Experiment – 5

Aim:

Write a program for page replacement algorithm:

a) LRU
b) FIFO
c) Optimal

a)

Theory:

In Least Recently Used (LRU) algorithm is a Greedy algorithm where the page to
be replaced is least recently used. The idea is based on locality of reference, the
least recently used page is not likely.
Let say the page reference string 7 0 1 2 0 3 0 4 2 3 0 3 2 . Initially we have 4
page slots empty.
Initially all slots are empty, so when 7 0 1 2 are allocated to the empty slots —> 4
Page faults
0 is already their so —> 0 Page fault.
When 3 came it will take the place of 7 because it is least recently used —>1
Page fault
0 is already in memory so —> 0 Page fault.
4 will takes place of 1 —> 1 Page Fault
Now for the further page reference string —> 0 Page fault because they are
already available in the memory.

29
Program:

import java.util.*;

public class pract{

public static void main(String[] args) {

Scanner scn = new Scanner(System.in);

System.out.println("Enter no of frames :");

int frames = scn.nextInt();

System.out.println("Enter total no of pages : ");

int n = scn.nextInt();

System.out.println("Enter pages :");

int[] page = new int[n];

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

page[i] = scn.nextInt();

Set<Integer> fm = new HashSet<>();

Set<Integer> dqSet = new HashSet<>();

ArrayList<Integer> dq = new ArrayList<>();

int hit = 0;

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

int cur = page[i];

if(fm.contains(cur)){

30
System.out.println(cur + " : Hit");

hit++;

}else{

if(fm.size() < frames){

fm.add(cur);

}else{

for(int x = 0;x < dq.size();x++){

if(fm.contains(dq.get(x))){

fm.remove(dq.get(x));

fm.add(cur);

break;

System.out.println(cur + " : Fault");

if(dqSet.contains(cur)){

dq.remove(new Integer(cur));

dq.add(cur);

}else{

dq.add(cur);

dqSet.add(cur);

31
}

System.out.println("Total Hits : " + (hit));

System.out.println("Total Fault : " + (n - hit));

Output:

b)

32
Theory:

This is the simplest page replacement algorithm. In this algorithm, operating


system keeps track of all pages in the memory in a queue, oldest page is in the
front of the queue. When a page needs to be replaced page in the front of the
queue is selected for removal.

Consider page reference string 1, 3, 0, 3, 5, 6 and 3 page slots.

Initially all slots are empty, so when 1, 3, 0 came they are allocated to the empty
slots
—> 3 Page Faults.
When 3 comes, it is already in memory so —> 0 Page Faults.
Then 5 comes, it is not available in memory so it replaces the oldest page slot i.e
1.—>1 Page Fault.
Finally 6 comes, it is also not available in memory so it replaces the oldest page
slot i.e
3 —>1 Page Fault.
Sototalpagefaults=5.

Program:

import java.util.*;

public class pract{

public static void main(String[] args) {

Scanner scn = new Scanner(System.in);

System.out.println("Enter no of frames :");

int frames = scn.nextInt();

System.out.println("Enter total no of pages : ");

int n = scn.nextInt();

System.out.println("Enter pages :");

int[] page = new int[n];

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

page[i] = scn.nextInt();

Set<Integer> fm = new HashSet<>();

ArrayDeque<Integer> dq = new ArrayDeque<>();

int hit = 0;

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

int cur = page[i];

if(fm.contains(cur)){

hit++;

System.out.println(cur + " : Hit");

}else{

if(fm.size() < frames){

fm.add(cur);

dq.addLast(cur);

}else{

int rem = dq.removeFirst();

fm.remove(rem);

dq.addLast(cur);

fm.add(cur);

System.out.println(cur + " : Fault");

34
}

System.out.println("Total Hits : " + (hit));

System.out.println("Total Fault : " + (n - hit));

Output:

c)

Theory:

In this algorithm, pages are replaced which would not be used for the longest

35
duration of time in the future. Optimal page replacement is perfect, but not
possible in practice as the operating system cannot know future requests. The
use of Optimal Page replacement is to set up a benchmark so that other
replacement algorithms can be analyzed against it.

Consider the page references 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, with 4 page frame.


Find number of page fault.

Program:

import java.util.*;

public class pract{

public static void main(String[] args) {

Scanner scn = new Scanner(System.in);

System.out.println("Enter no of frames :");

int frames = scn.nextInt();

System.out.println("Enter total no of pages : ");

int n = scn.nextInt();

System.out.println("Enter pages :");

int[] page = new int[n];

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

page[i] = scn.nextInt();

Set<Integer> fm = new HashSet<>();

int hit = 0;

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

Iterator iix = fm.iterator();

while(iix.hasNext()){

int vv = (int)iix.next();

System.out.print(vv + ", ");

System.out.println();

int cur = page[i];

if(fm.contains(cur)){

hit++;

System.out.println(cur + " : Hit");

}else{

if(fm.size() < frames){

fm.add(cur);

}else{

Set<Integer> dqSet = new HashSet<>();

ArrayDeque<Integer> dq = new ArrayDeque<>();

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

if(dq.size() == frames){

break;

if(fm.contains(page[x])){

if(!dqSet.contains(page[x])){

dq.addFirst(page[x]);

dqSet.add(page[x]);

if(dq.size()==0){

int vv = fm.iterator().next();

dq.addFirst(vv);

if(dq.size()==1){

int fn = dq.peek();

Iterator ii = fm.iterator();

while(ii.hasNext()){

int vv = (int)ii.next();

if(vv != fn){

dq.addFirst(vv);

38
}

fm.remove(new Integer(dq.getFirst()));

fm.add(cur);

System.out.println(cur + " : Fault");

System.out.println("Total Hits : " + (hit));

System.out.println("Total Fault : " + (n - hit));

Output:

39
40
Experiment – 6

Aim:

Write a program to implement first fit, best fit and worst fit algorithm for memory
management.

First Fit:

Theory:

In the first fit approach is to allocate the first free partition or hole large enough
which can accommodate the process. It finishes after finding the first suitable
free partition.
Advantage:
Fastest algorithm because it searches as little as possible.
Disadvantage:
The remaining unused memory areas left after allocation become waste if
it is too smaller. Thus request for larger memory requirement cannot be
accomplished.
Program:
import java.util.*;

public class pract{


public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
System.out.println("Enter total no of blocks: ");
int b = scn.nextInt();
System.out.println("Enter blocks size : ");
int[] block = new int[b];
int[] bs = new int[b];
for (int i = 0 ; i < b ; i++){
block[i] = scn.nextInt();
bs[i] = block[i];

41
}

System.out.println("Enter no of process: ");


int n = scn.nextInt();
System.out.println("Enter process size: ");
int[] process = new int[n];
for(int i = 0; i < n;i++){
process[i] = scn.nextInt();
}
int id = 0;
int[] assigned = new int[n];
while(id < n){
boolean flag = false;
for(int j = 0;j < b;j++){
if(process[id] <= block[j]){
assigned[id] = j + 1;
block[j] -= process[id];
flag = true;
break;
}
}
if(!flag){
assigned[id] = -1;
}
id++;
}
System.out.println("PId\tProcess Size Alotted Block");
for(int i = 0; i < n;i++){
System.out.print((i + 1) +"\t" + process[i]+"\t\t" );
if(assigned[i] == -1){
System.out.println("Not assigned");

42
}else{
System.out.println(assigned[i]);
}
}
}
}

Output:

Best Fit:
Theory:
The best fit deals with allocating the smallest free partition which meets the
requirement of the requesting process. This algorithm first searches the entire
list of free partitions and considers the smallest hole that is adequate. It then
tries to find a hole which is close to actual process size needed.
Advantage:
Memory utilization is much better than first fit as it searches the smallest
free partition first available.
Disadvantage:

43
It is slower and may even tend to fill up memory with tiny useless holes.

Program:
import java.util.*;
public class pract{
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
System.out.println("Enter total no of blocks: ");
int b = scn.nextInt();
System.out.println("Enter blocks size : ");
int[] block = new int[b];
int[] bs = new int[b];
for (int i = 0 ; i < b ; i++){
block[i] = scn.nextInt();
bs[i] = block[i];
}

System.out.println("Enter no of process: ");


int n = scn.nextInt();
System.out.println("Enter process size: ");
int[] process = new int[n];
for(int i = 0; i < n;i++){
process[i] = scn.nextInt();
}
int id = 0;
int[] assigned = new int[n];
while(id < n){
boolean flag = false;
int least = Integer.MAX_VALUE;
int selected = -1;
for(int j = 0;j < b;j++){

44
if(process[id] <= block[j]){
if(block[j] - process[id] < least){
selected = j;
least = block[j] - process[id];
}
}
}
if(selected == -1){
assigned[id] = -1;
}else{
assigned[id] = selected + 1;
block[selected] -= process[id];
}
id++;
}
System.out.println("PId\tProcess Size Alotted Block");
for(int i = 0; i < n;i++){
System.out.print((i + 1) +"\t" + process[i]+"\t\t" );
if(assigned[i] == -1){
System.out.println("Not assigned");
}else{
System.out.println(assigned[i]);
}
}
}
}
Output:

45
Worst Fit:

Theory:

In worst fit approach is to locate largest available free portion so that the
portion left will be big enough to be useful. It is the reverse of best fit.
Advantage:
Reduces the rate of production of small gaps.
Disadvantage:
If a process requiring larger memory arrives at a later stage then it cannot
be accommodated as the largest hole is already split and occupied.

Program:
import java.util.*;

public class pract{


public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
System.out.println("Enter total no of blocks: ");
int b = scn.nextInt();

46
System.out.println("Enter blocks size : ");
int[] block = new int[b];
int[] bs = new int[b];
for (int i = 0 ; i < b ; i++){
block[i] = scn.nextInt();
bs[i] = block[i];
}

System.out.println("Enter no of process: ");


int n = scn.nextInt();
System.out.println("Enter process size: ");
int[] process = new int[n];
for(int i = 0; i < n;i++){
process[i] = scn.nextInt();
}
int id = 0;
int[] assigned = new int[n];
while(id < n){
boolean flag = false;
int least = Integer.MIN_VALUE;
int selected = -1;
for(int j = 0;j < b;j++){
if(process[id] <= block[j]){
if(block[j] - process[id] > least){
selected = j;
least = block[j] - process[id];
}
}
}
if(selected == -1){
assigned[id] = -1;

47
}else{
assigned[id] = selected + 1;
block[selected] -= process[id];
}
id++;
}
System.out.println("PId\tProcess Size Alotted Block");
for(int i = 0; i < n;i++){
System.out.print((i + 1) +"\t" + process[i]+"\t\t" );
if(assigned[i] == -1){
System.out.println("Not assigned");
}else{
System.out.println(assigned[i]);
}
}
}
}
Output:

48
Experiment – 7

Aim:

Write a program to implement reader/writer problem using semaphore.

Theory:

The readers-writers problem relates to an object such as a file that is shared


between multiple processes. Some of these processes are readers i.e. they only
want to read the data from the object and some of the processes are writers i.e.
they want to write into the object.
The readers-writers problem is used to manage synchronization so that there are
no problems with the object data. For example - If two readers access the object
at the same time there is no problem. However if two writers or a reader and
writer access the object at the same time, there may be problems.
To solve this situation, a writer should get exclusive access to an object i.e. when
a writer is accessing the object, no reader or writer may access it. However,
multiple readers can access the object at the same time.
Writer
while(TRUE)
{
wait(w);
/* perform the write operation */
signal(w);
}
Reader
while(TRUE)
{
//acquire lock
wait(m);
read_count++;
if(read_count == 1)
wait(w);

49
//release lock
signal(m);
/* perform the reading operation */
// acquire lock
wait(m);
read_count--;
if(read_count == 0)
signal(w);
// release lock
signal(m);
}

Program:
import java.util.concurrent.Semaphore;

public class pract{

static Semaphore readLock = new Semaphore(1);

static Semaphore writeLock = new Semaphore(1);

static int readCount = 0;

static class Read implements Runnable {

@Override

public void run() {

try {

readLock.acquire();

readCount++;

if (readCount == 1) {

50
writeLock.acquire();

readLock.release();

System.out.println(Thread.currentThread().getName() + " is READING");

Thread.sleep(2000);

System.out.println(Thread.currentThread().getName() + " has FINISHED


READING");

readLock.acquire();

readCount--;

if(readCount == 0) {

writeLock.release();

readLock.release();

} catch (InterruptedException e) {

System.out.println(e.getMessage());

static class Write implements Runnable {

@Override

public void run() {

try {

writeLock.acquire();

51
System.out.println(Thread.currentThread().getName() + " is WRITING");

Thread.sleep(3000);

System.out.println(Thread.currentThread().getName() + " has finished


WRITING");

writeLock.release();

} catch (InterruptedException e) {

System.out.println(e.getMessage());

public static void main(String[] args) throws Exception {

Read read = new Read();

Write write = new Write();

Thread t1 = new Thread(read);

t1.setName("Client 1");

Thread t2 = new Thread(read);

t2.setName("Client 2");

Thread t3 = new Thread(write);

t3.setName("Client 3");

Thread t4 = new Thread(read);

t4.setName("Client 4");

t1.start();

t3.start();

52
t2.start();

t4.start();

Output:

53
Experiment – 8

Aim:

Write a program to implement Banker 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 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.

Example:

Considering a system with five processes P0 through P4 and three resources


types A, B, C. Resource type A has 10 instances, B has 5 instances and type C
has 7 instances. Suppose at time t0 following snapshot of the system has been
taken:

Result:

54
Program:

import java.util.*;

class process{

int[] allocated;

int pid;

int[] available;

int[] maximum;

public process(int size){

allocated = new int[size];

available = new int[size];

maximum = new int[size];

public class pract{

public static void main(String[] args) {

Scanner scn = new Scanner(System.in);

System.out.println("Enter total process : ");

int n = scn.nextInt();

System.out.println("Enter total resources :");

int res = scn.nextInt();

System.out.println("Enter total available resources :");

55
int[] remain = new int[res];

for(int j = 0; j < res;j++){

remain[j] = scn.nextInt();

System.out.println("PID\t Allocated\t Maximum");

ArrayList<process> list = new ArrayList<>();

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

process np = new process(res);

np.pid = scn.nextInt();

for(int j = 0; j < res;j++){

np.allocated[j] = scn.nextInt();

for(int j = 0; j < res;j++){

np.maximum[j] = scn.nextInt();

np.available[j] = np.maximum[j] - np.allocated[j];

list.add(np);

for(int j = 0 ; j < res;j++){

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

remain[j] -= list.get(i).allocated[j];

56
int solved = 0;

boolean state = true;

String ans = "";

while(solved < n){

int idx = -1;

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

boolean flag = true;

for(int j = 0 ;j < res;j++){

if(list.get(i).available[j] > remain[j]){

flag = false;

break;

if(flag){

idx = i;

break;

if(idx == -1){

state = false;

break;

}else{

for(int j = 0; j < res;j++){

57
remain[j] += list.get(idx).allocated[j];

ans += "[ P" + list.get(idx).pid + " ] ";

list.remove(idx);

solved++;

if(state){

System.out.println("System is in safe state !!");

System.out.println(ans);

}else{

System.out.println("System is not in safe state !! Deadlock may occur");

Output:

58
59

You might also like