“Practical 1 “
import threading
import random4
import time
buffer_size= 5
buffer=[]
buffer_locks = threading.Lock()
empty_slots=threading.Semaphore(buffer_size)
full_slots = threading.Semaphore(0)
def producer():
  for i in range(10):
     item=random.randint(1,100)
     empty_slots.acquire()
     with buffer_locks:
        buffer.append(item)
        print(f"producer produced:{item}")
     full_slots.release()
def consumer():
  for i in range(10):
     full_slots.acquire()
     with buffer_locks:
        item = buffer.pop(0)
        print(f"consumer consumed {item}")
     empty_slots.release()
if __name__ == "__main__":
   producer_thread = threading .Thread(target=producer)
   consumer_thread = threading.Thread(target=consumer)
  producer_thread.start()
  consumer_thread.start()
  producer_thread.join()
  consumer_thread.join()
pactical 2
# Input data
processes = [1, 2, 3, 4, 5]
bt = [11, 22, 33, 44, 55]
n = len(processes)
wt = [0] * n # Initialize waiting times
tt = [0] * n # Initialize turnaround times
# Calculate waiting time
for i in range(1, n): # Start from 1 to avoid index-out-of-bounds
   wt[i] = wt[i-1] + bt[i-1]
# Calculate turnaround time
for i in range(n):
   tt[i] = bt[i] + wt[i]
# Calculate total waiting and turnaround times
total_wt = sum(wt)
total_tt = sum(tt)
# Print process details
print("Processes\tBurst Time\tWaiting Time\tTurnaround Time")
for i in range(n):
   print(f"{processes[i]}\t\t{bt[i]}\t\t{wt[i]}\t\t{tt[i]}")
# Print averages
print(f"\nAverage Waiting Time: {total_wt / n:.2f}")
print(f"Average Turnaround Time: {total_tt / n:.2f}")
os pract 3
import threading
import time
import random
BUFFER_SIZE = 5
NUM_ITEMS = 10
buffer = []
buffer_lock = threading.Lock()
not_full = threading.Condition(buffer_lock)
not_empty = threading.Condition(buffer_lock)
def producer():
  for i in range(NUM_ITEMS):
     item = f'item-{i}'
     with not_full:
        while len(buffer) == BUFFER_SIZE:
           print("Buffer is full. Producer is waiting.")
           not_full.wait()
        buffer.append(item)
        print(f'Produced: {item} | Buffer Index: {len(buffer) - 1}')
        not_empty.notify()
     time.sleep(random.uniform(0.1, 0.5))
def consumer():
  for _ in range(NUM_ITEMS):
    with not_empty:
       while len(buffer) == 0:
          print("Buffer is empty. Consumer is waiting.")
          not_empty.wait()
       item = buffer.pop(0)
       print(f'Consumed: {item} | Remaining Items: {len(buffer)}')
       not_full.notify()
    time.sleep(random.uniform(0.1, 0.5))
if __name__ == "__main__":
   producer_thread = threading.Thread(target=producer)
   consumer_thread = threading.Thread(target=consumer)
  producer_thread.start()
  consumer_thread.start()
  producer_thread.join()
  consumer_thread.join()
  print("Production and consumption complete")
#ospract4
import threading
class ReadersWriters:
   def __init__(self):
     self.read_count = 0
     self.resource_lock = threading.Lock()
     self.read_count_lock = threading.Lock()
  def reader(self, reader_id):
    while True:
       with self.read_count_lock:
          self.read_count += 1
          if self.read_count == 1:
             self.resource_lock.acquire()
       print(f"Reader {reader_id} is reading.")
       threading.Event().wait(1)
       print(f"Reader {reader_id} has finished reading.")
       with self.read_count_lock:
          self.read_count -= 1
          if self.read_count == 0:
             self.resource_lock.release()
       break
  def writer(self, writer_id):
    while True:
       self.resource_lock.acquire()
       print(f"Writer {writer_id} is writing.")
       threading.Event().wait(2)
       print(f"Writer {writer_id} has finished writing.")
       self.resource_lock.release()
       break
if __name__ == "__main__":
   rw = ReadersWriters()
   threads = []
  for i in range(3):
     t = threading.Thread(target=rw.reader, args=(i+1,))
     threads.append(t)
  for i in range(2):
     t = threading.Thread(target=rw.writer, args=(i+1,))
     threads.append(t)
  for t in threads:
     t.start()
  for t in threads:
     t.join()
  print("All readers and writers have finished.")
practical 8
#prctos 8
def print_tbl(alloc, max_d, avail, need):
  print("\nP\tAlloc\t\tMax\t\t\tAvail\t\tNeed")
  for i in range(len(alloc)):
     print(f"P{i}\t{alloc[i]}\t{max_d[i]}\t{avail if i == 0 else ' '}\t{need[i]}")
def is_safe(p, avail, alloc, need):
  work, finish, seq = avail.copy(), [False] * p, []
  while True:
      found = False
      for i in range(p):
         if not finish[i] and all(need[i][j] <= work[j] for j in range(len(work))):
            work = [work[j] + alloc[i][j] for j in range(len(work))]
            finish[i], seq, found = True, seq + [i], True
     if not found: break
  return all(finish), seq
def banker_algo():
  p, r = 5, 3 # Number of processes and resources
  alloc = [[0, 1, 0], [2, 0, 0], [3, 0, 3], [2, 1, 1], [0, 0, 2]]
  max_d = [[7, 5, 3], [3, 2, 2], [9, 0, 5], [2, 2, 2], [4, 3, 3]]
  avail = [3, 3, 2]
  need = [[max_d[i][j] - alloc[i][j] for j in range(r)] for i in range(p)]
  # Check if the system is in a safe state
  safe, seq = is_safe(p, avail, alloc, need)
  print("\nSystem is in a safe state." if safe else "\nSystem is in an unsafe state.")
  if safe: print("Process execution sequence:", " -> ".join(f"P{i}" for i in seq))
  # Process P1 requesting resources
  req_p, req = 1, [1, 0, 2]
  print(f"\nP{req_p} is requesting: {req}")
  if all(req[j] <= need[req_p][j] for j in range(r)) and all(req[j] <= avail[j] for j in range(r)):
     # Temporarily allocate resources
     for j in range(r):
        avail[j] -= req[j]
        alloc[req_p][j] += req[j]
        need[req_p][j] -= req[j]
     # Check if the system is still in a safe state
     safe, seq = is_safe(p, avail, alloc, need)
     print("Request granted." if safe else "Request denied. Unsafe state.")
     if not safe: # Rollback if unsafe
        for j in range(r):
           avail[j] += req[j]
           alloc[req_p][j] -= req[j]
           need[req_p][j] += req[j]
  else:
     print("Request denied. Not enough resources or exceeds need.")
  # Print the updated table
  print_tbl(alloc, max_d, avail, need)
if __name__ == "__main__":
   banker_algo()
practical 9
#withtcmntpcos9
#1 2 3 4 1 2 5 1 2 3 4 5 iput me dalna hai
def fifo(pagestring, msize):
  mptr, hit, miss = 0, 0, 0
  memory = [-1 for _ in range(msize)]
  for page in pagestring:
     flag = 0
     for j in memory:
        if j == int(page):
            hit += 1
            flag = 1
            break
     if flag == 0:
        miss += 1
        memory[mptr] = int(page)
        mptr += 1
        if mptr == msize:
           mptr = 0
     print(memory)
  return miss
def main():
  x = input("Enter the page string (space-separated): ").split()
  m = int(input("Enter the size of memory: "))
  page_faults = fifo(x, m)
  print(f"Total Page Faults: {page_faults}")
if __name__ == "__main__":
   main()
practical 10
"""practos10lru"""
from collections import OrderedDict
class LRUCache:
   def __init__(self, capacity):
     self.capacity = capacity
     self.cache = OrderedDict()
  def get(self, page):
    if page in self.cache:
       self.cache.move_to_end(page)
       return True
    return False
  def put(self, page):
    if page in self.cache:
       self.cache.move_to_end(page)
    elif len(self.cache) >= self.capacity:
       self.cache.popitem(last=False)
    self.cache[page] = None
def main():
  n = int(input("Enter the number of pages: "))
  frame_size = int(input("Enter the number of frames: "))
  pages = []
  print("Enter the reference string (space-separated):")
  pages = list(map(int, input().split()))
  cache = LRUCache(frame_size)
  page_faults = 0
  page_hits = 0
  for page in pages:
     if not cache.get(page):
        page_faults += 1
        cache.put(page)
     else:
        page_hits += 1
     print(f"Memory after accessing page {page}: {list(cache.cache.keys())}")
  print(f"Page Faults: {page_faults}")
  print(f"Page Hits: {page_hits}")
if __name__ == "__main__":
   main()
"""Enter the number of pages: 7
Enter the number of frames: 3
Enter the reference string (space-separated): 1 2 3 4 2 1 5
Memory after accessing page 1: [1]
Memory after accessing page 2: [1, 2]
Memory after accessing page 3: [1, 2, 3]
Memory after accessing page 4: [2, 3, 4]
Memory after accessing page 2: [3, 4, 2]
Memory after accessing page 1: [4, 2, 1]
Memory after accessing page 5: [2, 1, 5]
Page Faults: 6
Page Hits: 1
"""
practical 6
class Process:
   def __init__(self, name, burst_time, priority):
     self.name = name
     self.burst_time = burst_time
     self.priority = priority
def priority_scheduling(processes):
  processes.sort(key=lambda x: x.priority)
  total_burst_time = sum(process.burst_time for process in processes)
  current_time = 0
   print("Priority Scheduling Execution Order:")
   print(f"{'Process':<10}{'Burst Time':<15}{'Prio rity':<10}{'Start Time':<12}{'Finish Time':<12}
{'Turnaround Time':<15}{'Waiting Time':<15}")
  total_turnaround_time = 0
  total_waiting_time = 0
  for process in processes:
     start_time = current_time
     finish_time = start_time + process.burst_time
     turnaround_time = finish_time
     waiting_time = turnaround_time - process.burst_time
     print(f"{process.name:<10}{process.burst_time:<15}{process.priority:<10}{start_time:<12}
{finish_time:<12}{turnaround_time:<15}{waiting_time:<15}")
     current_time = finish_time
     total_turnaround_time += turnaround_time
     total_waiting_time += waiting_time
  print(f"\nTotal Turnaround Time: {total_turnaround_time}")
  print(f"Total Waiting Time: {total_waiting_time}")
process_list = [
  Process('P1', 4, 3),
  Process('P2', 5, 1),
  Process('P3', 6, 4),
  Process('P4', 2, 2),
]
priority_scheduling(process_list)
os pract 7
def round_robin(processes, burst_times, time_quantum):
  n = len(processes)
  remaining_burst_times = burst_times[:]
  waiting_time = [0] * n
  turnaround_time = [0] * n
  completion_time = [0] * n
  current_time = 0
  print("Gantt Chart Execution Order:")
  while any(rt > 0 for rt in remaining_burst_times):
    for i in range(n):
       if remaining_burst_times[i] > 0:
          print(f"P{processes[i]} ", end="")
          time_slice = min(remaining_burst_times[i], time_quantum)
          current_time += time_slice
          remaining_burst_times[i] -= time_slice
          if remaining_burst_times[i] == 0:
             completion_time[i] = current_time
  for i in range(n):
     turnaround_time[i] = completion_time[i]
     waiting_time[i] = turnaround_time[i] - burst_times[i]
    print("\n\nProcess Execution Results:")
    print("Process\tBurst Time\tWaiting Time\tTurnaround Time\tCompletion Time")
    for i in range(n):
       print(
          f"P{processes[i]}\t{burst_times[i]}\t\t{waiting_time[i]}\t\t{turnaround_time[i]}
\t\t{completion_time[i]}"
       )
# Define the processes and their burst times
processes = [1, 2, 3]
burst_times = [10, 5, 8]
time_quantum = 4
# Call the round robin function
round_robin(processes, burst_times, time_quantum)
pract05
def fcfs_scheduling(processes, arrival_time, burst_time):
  n = len(processes)
  completion_time = [0] * n
  turnaround_time = [0] * n
  waiting_time = [0] * n
  sorted_processes = sorted(zip(processes, arrival_time, burst_time), key=lambda x: x[1])
  processes, arrival_time, burst_time = zip(*sorted_processes)
  for i in range(n):
     if i == 0:
         completion_time[i] = arrival_time[i] + burst_time[i]
     else:
         completion_time[i] = max(completion_time[i - 1], arrival_time[i]) + burst_time[i]
  for i in range(n):
     turnaround_time[i] = completion_time[i] - arrival_time[i]
     waiting_time[i] = turnaround_time[i] - burst_time[i]
  avg_tat = sum(turnaround_time) / n
  avg_wt = sum(waiting_time) / n
    print("Process\tArrival Time\tBurst Time\tCompletion Time\tTurnaround Time\tWaiting Time")
    for i in range(n):
       print(f"{processes[i]}\t{arrival_time[i]}\t\t{burst_time[i]}\t\t{completion_time[i]}
\t\t{turnaround_time[i]}\t\t{waiting_time[i]}")
  print(f"\nAverage Turnaround Time: {avg_tat:.2f}")
  print(f"Average Waiting Time: {avg_wt:.2f}")
processes = [1, 2, 3, 4]
arrival_time = [0, 2, 4, 6]
burst_time = [8, 4, 2, 1]
fcfs_scheduling(processes, arrival_time, burst_time)