Professional Documents
Culture Documents
2 Labda
2 Labda
Operating Systems
Hridyesh Das 21BDS0167
Question
a) Write a program to avoid deadlock using
Banker’s algorithm ( Safety Sequence Algorithm
).
b) #include <iostream>
c) #include <vector>
d) #include <algorithm>
e)
f) using namespace std;
g)
h) // Function to check if a process can be allocated resources
i) bool canAllocateResources(const vector<vector<int>>& max, const
vector<vector<int>>& allocated, const vector<vector<int>>& need,
const vector<int>& available, int process)
j) {
k) int numResources = available.size();
l)
m) // Check if the requested resources are available
n) for (int i = 0; i < numResources; i++) {
o) if (need[process][i] > available[i])
p) return false;
q) }
r)
s) return true;
t) }
u)
v) // Function to find the safety sequence using Banker's algorithm
w) vector<int> findSafetySequence(const vector<vector<int>>& max, const
vector<vector<int>>& allocated, const vector<int>& available)
x) {
y) int numProcesses = max.size();
z) int numResources = available.size();
aa)
bb) // Initialize the need matrix
cc) vector<vector<int>> need(numProcesses, vector<int>(numResources));
dd) for (int i = 0; i < numProcesses; i++) {
ee) for (int j = 0; j < numResources; j++) {
ff) need[i][j] = max[i][j] - allocated[i][j];
gg) }
hh) }
ii)
jj) // Initialize the finish and safety sequence vectors
kk) vector<bool> finish(numProcesses, false);
ll) vector<int> safetySequence;
mm)
nn) // Initialize the work and available vectors
oo) vector<int> work = available;
pp)
qq) // Find a safe sequence
rr) int count = 0;
ss) while (count < numProcesses) {
tt) bool found = false;
uu) for (int i = 0; i < numProcesses; i++) {
vv) if (!finish[i] && canAllocateResources(max, allocated, need,
work, i)) {
ww) // Allocate resources
xx) for (int j = 0; j < numResources; j++) {
yy) work[j] += allocated[i][j];
zz) }
aaa)
bbb) // Mark the process as finished and add it to the
safety sequence
ccc) finish[i] = true;
ddd) safetySequence.push_back(i);
eee)
fff) found = true;
ggg) count++;
hhh) break;
iii) }
jjj) }
kkk)
lll) if (!found) {
mmm) // No process found that can be allocated resources
nnn) break;
ooo) }
ppp) }
qqq)
rrr) // If a safety sequence is found, return it
sss) if (count == numProcesses) {
ttt) return safetySequence;
uuu) }
vvv)
www) // If no safety sequence is found, return an empty sequence
xxx) return {};
yyy) }
zzz)
aaaa) int main()
bbbb) {
cccc) int numProcesses, numResources;
dddd)
eeee) cout << "Enter the number of processes: ";
ffff) cin >> numProcesses;
gggg)
hhhh) cout << "Enter the number of resources: ";
iiii) cin >> numResources;
jjjj)
kkkk) // Initialize the max matrix
llll) vector<vector<int>> max(numProcesses,
vector<int>(numResources));
mmmm) cout << "Enter the maximum demand of each process for
each resource:\n";
nnnn) for (int i = 0; i < numProcesses; i++) {
oooo) cout << "Process " << i << ": ";
pppp) for (int j = 0; j < numResources; j++) {
qqqq) cin >> max[i][j];
rrrr) }
ssss) }
tttt)
uuuu) // Initialize the allocated matrix
vvvv) vector<vector<int>>
allocated(numProcesses, vector<int>(numResources));
wwww) cout << "Enter the allocated resources of each process for
each resource:\n";
xxxx) for (int i = 0; i < numProcesses; i++) {
yyyy) cout << "Process " << i << ": ";
zzzz) for (int j = 0; j < numResources; j++) {
aaaaa) cin >> allocated[i][j];
bbbbb) }
ccccc) }
ddddd)
eeeee) // Initialize the available vector
fffff) vector<int> available(numResources);
ggggg) cout << "Enter the available resources for each resource:\n";
hhhhh) for (int i = 0; i < numResources; i++) {
iiiii) cin >> available[i];
jjjjj) }
kkkkk)
lllll) // Find the safety sequence
mmmmm) vector<int> safetySequence = findSafetySequence(max,
allocated, available);
nnnnn)
ooooo) if (safetySequence.empty()) {
ppppp) cout << "No safety sequence exists. Deadlock detected!\n";
qqqqq) } else {
rrrrr) cout << "Safety sequence: ";
sssss) for (int i = 0; i < safetySequence.size(); i++) {
ttttt) cout << safetySequence[i];
uuuuu) if (i != safetySequence.size() - 1) {
vvvvv) cout <<"->";
wwwww) }
xxxxx) }
yyyyy) cout << "\n";
zzzzz) }
aaaaaa)
bbbbbb) return 0;
cccccc) }
dddddd)
Output
b) Implement Bankers-additional
resource request algorithm
#include <iostream>
#include <vector>
#include <algorithm>
return true;
}
if (!found) {
/ No process found that can be allocated
resources break;
}
}
return true;
}
// Function to handle additional resource requests
bool handleResourceRequest(vector<vector<int>>& max,
vector<vector<int>>& allocated,
vector<int>& available, int process, const
vector<int>& request)
{
int numResources = available.size();
if (!safetySequence.empty()) {
cout << "Request can be granted. Safety sequence: ";
for (int i = 0; i < safetySequence.size(); i++) {
cout << safetySequence[i];
if (i != safetySequence.size() - 1) {
cout << " -> ";
}
}
cout << "\n";
return true;
} else {
/ Roll back the allocation
for (int i = 0; i < numResources; i++) {
allocated[process][i] -= request[i];
available[i] += request[i];
max[process][i] += request[i];
}
cout << "Request cannot be granted. Deadlock detected!\
n"; return false;
}
}
int main()
{
int numProcesses, numResources;
if (safetySequence.empty()) {
cout << "No safety sequence exists. Deadlock detected!\n";
} else {
cout << "Safety sequence: ";
for (int i = 0; i < safetySequence.size(); i++)
{ cout << safetySequence[i];
if (i != safetySequence.size() - 1) {
cout << " -> ";
}
}
cout << "\n";
}
cout << "Enter the additional resource request for process " << process
<< ":\n";
for (int i = 0; i < numResources; i++) {
cin >> request[i];
}
return 0;
}
Output
buffer = []
mutex = Semaphore(1) # Semaphore to control access to the buffer
empty = Semaphore(BUFFER_SIZE) # Semaphore to track empty slots in the buffer
full = Semaphore(0) # Semaphore to track filled slots in the buffer
def producer():
for _ in range(NUM_ITEMS):
item = random.randint(1, 100) # Generate a random item
empty.acquire() # Wait for an empty slot in the buffer
mutex.acquire() # Obtain exclusive access to the buffer
buffer.append(item) # Add item to the buffer
print("Producer produced item:", item) mutex.release()
# Release the mutex
full.release() # Notify consumer that the buffer is no longer empty
time.sleep(random.random()) # Sleep for a random time
def consumer():
for _ in range(NUM_ITEMS):
full.acquire() # Wait for a filled slot in the buffer
mutex.acquire() # Obtain exclusive access to the buffer
item = buffer.pop(0) # Remove item from the buffer
print("Consumer consumed item:", item) mutex.release()
# Release the mutex
empty.release() # Notify producer that the buffer is no longer full
time.sleep(random.random()) # Sleep for a random time
print("Program completed.")
Output
readers = []
writers = []
def reader(reader_id):
global read_count
while True:
time.sleep(random.random()) # Simulate reading time
mutex.acquire() # Obtain exclusive access to the read_count variable
read_count += 1 # Increment the number of readers
if read_count == 1:
resource.acquire() # If this is the first reader, acquire the
resource
mutex.release() # Release the mutex
def writer(writer_id):
while True:
time.sleep(random.random()) # Simulate writing time
print("Program completed.")
Output
E ) Implement a solution for the classical
synchronization problem: Dining Philosophers
using monitor(User defined Constructs).
from threading import Thread, Condition
import time
import random
class DiningPhilosophers:
def __init__(self):
self.forks = [Condition() for _ in range(NUM_PHILOSOPHERS)] # Forks as
conditions
self.is_fork_taken = [False] * NUM_PHILOSOPHERS # Track whether a fork
is taken
self.meals_count = [0] * NUM_PHILOSOPHERS # Track number of meals each
philosopher has eaten
return (
not self.is_fork_taken[left_philosopher_id] and
not self.is_fork_taken[right_philosopher_id]
)
# Hungry
print(f"Philosopher {philosopher_id} is hungry.")
with dining.forks[philosopher_id]:
while not dining.can_eat(philosopher_id):
dining.forks[philosopher_id].wait() # Wait until both forks are
available
dining.get_left_fork(philosopher_id)
dining.get_right_fork(philosopher_id)
# Eating
print(f"Philosopher {philosopher_id} is eating.")
time.sleep(EATING_TIME)
with dining.forks[philosopher_id]:
dining.release_forks(philosopher_id)
dining.increment_meals_count(philosopher_id)
dining.forks[philosopher_id].notify_all() # Notify other
philosophers that forks are available
print("Program completed.")
Output :