0% found this document useful (0 votes)
9 views21 pages

Python Process and Memory Management

The document outlines various programming functions related to process and memory management, including process management, file management, and different memory allocation strategies such as contiguous, linked list, and indirect allocation. It also covers algorithms for calculating average waiting times for different scheduling methods like SJF, Priority, and FCFS. Additionally, it discusses internal and external fragmentation in memory allocation and includes a resource allocation graph implementation.

Uploaded by

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

Python Process and Memory Management

The document outlines various programming functions related to process and memory management, including process management, file management, and different memory allocation strategies such as contiguous, linked list, and indirect allocation. It also covers algorithms for calculating average waiting times for different scheduling methods like SJF, Priority, and FCFS. Additionally, it discusses internal and external fragmentation in memory allocation and includes a resource allocation graph implementation.

Uploaded by

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

import os

def process_management():
# Process management
print("--- Process Management ---")
print("Current Process ID:", os.getpid())
print("Parent Process ID:", os.getppid())
print("Current Login Name:", os.getlogin()) # Getting login name
print("--------------------------")

def file_management():
# File management
print("--- File Management ---")
file_name = "test.txt"
file_content = "This is a test file.\nHello, World!"

# Writing to a file
with open(file_name, 'w') as f:
f.write(file_content)
print("File created and written successfully.")

# Reading from a file


with open(file_name, 'r') as f:
content = f.read()
print("File content:\n", content)
print("-----------------------")

def input_output_system_calls():
# Input / Output system calls
print("--- Input / Output System Calls ---")
print("Enter some text:")
user_input = input()
print("You entered:", user_input)
print("-----------------------------------")
if __name__ == "__main__":
process_management()
file_management()
input_output_system_calls()

import random

class Process:
def __init__(self, pid, burst_time, priority):
self.pid = pid
self.burst_time = burst_time
self.priority = priority
self.waiting_time = 0

def SJF(processes):
# Sort processes based on burst time
processes.sort(key=lambda x: x.burst_time)
total_waiting_time = 0
for i in range(len(processes)):
processes[i].waiting_time = total_waiting_time
total_waiting_time += processes[i].burst_time
return total_waiting_time / len(processes)

def Priority(processes):
# Sort processes based on priority
processes.sort(key=lambda x: x.priority)
total_waiting_time = 0
for i in range(len(processes)):
processes[i].waiting_time = total_waiting_time
total_waiting_time += processes[i].burst_time
return total_waiting_time / len(processes)

def FCFS(processes):
total_waiting_time = 0
for i in range(len(processes)):
processes[i].waiting_time = total_waiting_time
total_waiting_time += processes[i].burst_time
return total_waiting_time / len(processes)

def MultiLevelQueue(processes):
# Divide processes into two queues based on priority
high_priority_processes = [p for p in processes if p.priority == 1]
low_priority_processes = [p for p in processes if p.priority == 0]

# Calculate waiting time for high priority queue


total_waiting_time_high = FCFS(high_priority_processes)

# Calculate waiting time for low priority queue


total_waiting_time_low = FCFS(low_priority_processes)
# Return the average waiting time of both queues
return (total_waiting_time_high + total_waiting_time_low) / len(processes)

def generate_processes(num_processes):
processes = []
for i in range(num_processes):
burst_time = random.randint(1, 10)
priority = random.randint(0, 1)
processes.append(Process(i+1, burst_time, priority))
return processes

if __name__ == "__main__":
num_processes = 5
processes = generate_processes(num_processes)

print("Processes:")
for process in processes:
print("Process ID:", process.pid, "| Burst Time:", process.burst_time, "| Priority:", process.priority)

print("\nSJF Average Waiting Time:", SJF(processes))


print("Priority Average Waiting Time:", Priority(processes))
print("FCFS Average Waiting Time:", FCFS(processes))
print("Multi-level Queue Average Waiting Time:", MultiLevelQueue(processes))
class ContiguousAllocation:
def __init__(self, size):
self.size = size
self.blocks = [0] * size # 0 represents free block, 1 represents allocated block

def allocate(self, file_name, num_blocks):


allocated_blocks = []
for i in range(self.size):
if sum(self.blocks[i:i+num_blocks]) == 0:
self.blocks[i:i+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(i, i+num_blocks))
break
if allocated_blocks:
print(f"Allocated {file_name} at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def deallocate(self, file_name, blocks):


for block in blocks:
self.blocks[block] = 0
print(f"Deallocated {file_name} from blocks: {blocks}")
class LinkedListNode:
def __init__(self, data):
self.data = data
self.next = None

class LinkedListAllocation:
def __init__(self):
self.head = None

def allocate(self, file_name, num_blocks):


allocated_blocks = []
current = self.head
for i in range(num_blocks):
if current:
allocated_blocks.append(current.data)
current = current.next
else:
print(f"Error: Not enough space available to allocate {file_name}")
return
print(f"Allocated {file_name} at blocks: {allocated_blocks}")

def deallocate(self, file_name, blocks):


print(f"Deallocated {file_name} from blocks: {blocks}")

class IndirectAllocation:
def __init__(self, size):
self.size = size
self.blocks = [0] * size # 0 represents free block, 1 represents allocated block
self.index_blocks = [LinkedListAllocation() for _ in range(size)]

def allocate(self, file_name, num_blocks):


allocated_blocks = []
for i in range(self.size):
if self.blocks[i] == 0:
allocated_blocks.append(i)
self.blocks[i] = 1
for j in range(num_blocks-1):
i += 1
if i < self.size:
self.blocks[i] = 1
self.index_blocks[i].allocate(file_name, 1)
else:
print(f"Error: Not enough space available to allocate {file_name}")
self.deallocate(file_name, allocated_blocks)
return
print(f"Allocated {file_name} at blocks: {allocated_blocks}")
return
print(f"Error: Not enough space available to allocate {file_name}")

def deallocate(self, file_name, blocks):


for block in blocks:
self.blocks[block] = 0
self.index_blocks[block].deallocate(file_name, [block])
print(f"Deallocated {file_name} from blocks: {blocks}")

if __name__ == "__main__":
# Contiguous Allocation
print("Contiguous Allocation:")
contiguous_allocation = ContiguousAllocation(20)
contiguous_allocation.allocate("File1", 5)
contiguous_allocation.allocate("File2", 7)
contiguous_allocation.deallocate("File1", [0, 1, 2, 3, 4])

# Linked List Allocation


print("\nLinked List Allocation:")
linked_list_allocation = LinkedListAllocation()
linked_list_allocation.head = LinkedListNode(0)
linked_list_allocation.head.next = LinkedListNode(1)
linked_list_allocation.head.next.next = LinkedListNode(2)
linked_list_allocation.head.next.next.next = LinkedListNode(3)
linked_list_allocation.allocate("File1", 3)
linked_list_allocation.deallocate("File1", [0, 1, 2])

# Indirect Allocation
print("\nIndirect Allocation:")
indirect_allocation = IndirectAllocation(20)
indirect_allocation.allocate("File1", 5)
indirect_allocation.allocate("File2", 7)
indirect_allocation.deallocate("File2", [3, 4, 5, 6, 7, 8, 9])
class ContiguousAllocation:
def __init__(self, size):
self.size = size
self.blocks = [0] * size # 0 represents free block, 1 represents allocated block

def first_fit(self, file_name, num_blocks):


allocated_blocks = []
for i in range(self.size):
if sum(self.blocks[i:i+num_blocks]) == 0:
self.blocks[i:i+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(i, i+num_blocks))
break
if allocated_blocks:
print(f"Allocated {file_name} using First-Fit at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def best_fit(self, file_name, num_blocks):


best_fit_index = -1
min_free_blocks = float('inf')
for i in range(self.size):
if self.blocks[i] == 0:
j=i
while j < self.size and self.blocks[j] == 0:
j += 1
if j - i >= num_blocks and j - i < min_free_blocks:
best_fit_index = i
min_free_blocks = j - i
if best_fit_index != -1:
self.blocks[best_fit_index:best_fit_index+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(best_fit_index, best_fit_index+num_blocks))
print(f"Allocated {file_name} using Best-Fit at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def worst_fit(self, file_name, num_blocks):


worst_fit_index = -1
max_free_blocks = -1
for i in range(self.size):
if self.blocks[i] == 0:
j=i
while j < self.size and self.blocks[j] == 0:
j += 1
if j - i >= num_blocks and j - i > max_free_blocks:
worst_fit_index = i
max_free_blocks = j - i
if worst_fit_index != -1:
self.blocks[worst_fit_index:worst_fit_index+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(worst_fit_index, worst_fit_index+num_blocks))
print(f"Allocated {file_name} using Worst-Fit at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def deallocate(self, file_name, blocks):


for block in blocks:
self.blocks[block] = 0
print(f"Deallocated {file_name} from blocks: {blocks}")

if __name__ == "__main__":
contiguous_allocation = ContiguousAllocation(20)

# Perform allocations
contiguous_allocation.first_fit("File1", 5)
contiguous_allocation.best_fit("File2", 7)
contiguous_allocation.worst_fit("File3", 4)

# Deallocate a file
contiguous_allocation.deallocate("File2", [10, 11, 12, 13, 14, 15, 16])

print("\nRemaining free space:")


for i in range(len(contiguous_allocation.blocks)):
if contiguous_allocation.blocks[i] == 0:
print(f"Block {i} is free.")
class ContiguousAllocation:
def __init__(self, size):
self.size = size
self.blocks = [0] * size # 0 represents free block, 1 represents allocated block

def allocate(self, file_name, num_blocks):


allocated_blocks = []
for i in range(self.size):
if sum(self.blocks[i:i+num_blocks]) == 0:
self.blocks[i:i+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(i, i+num_blocks))
break
if allocated_blocks:
print(f"Allocated {file_name} at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def deallocate(self, file_name, blocks):


for block in blocks:
self.blocks[block] = 0
print(f"Deallocated {file_name} from blocks: {blocks}")
def calculate_internal_fragmentation(self, allocated_files):
total_internal_fragmentation = 0
for file_name, blocks in allocated_files.items():
total_internal_fragmentation += self.size - len(blocks)
return total_internal_fragmentation

def calculate_external_fragmentation(self):
unused_blocks = 0
for i in range(len(self.blocks)):
if self.blocks[i] == 0:
unused_blocks += 1
return unused_blocks

if __name__ == "__main__":
contiguous_allocation = ContiguousAllocation(20)

# Perform allocations
allocated_files = {"File1": [0, 1, 2, 3, 4], "File2": [7, 8, 9, 10, 11], "File3": [15, 16, 17, 18]}

for file_name, blocks in allocated_files.items():


contiguous_allocation.allocate(file_name, len(blocks))

# Deallocate a file
contiguous_allocation.deallocate("File2", [7, 8, 9, 10, 11])

print("\nRemaining free space:")


for i in range(len(contiguous_allocation.blocks)):
if contiguous_allocation.blocks[i] == 0:
print(f"Block {i} is free.")

internal_fragmentation = contiguous_allocation.calculate_internal_fragmentation(allocated_files)
print("\nTotal Internal Fragmentation:", internal_fragmentation)
external_fragmentation = contiguous_allocation.calculate_external_fragmentation()
print("Total External Fragmentation:", external_fragmentation)

class ContiguousAllocation:
def __init__(self, size):
self.size = size
self.blocks = [0] * size # 0 represents free block, 1 represents allocated block

def allocate(self, file_name, num_blocks):


allocated_blocks = []
for i in range(self.size):
if sum(self.blocks[i:i+num_blocks]) == 0:
self.blocks[i:i+num_blocks] = [1] * num_blocks
allocated_blocks = list(range(i, i+num_blocks))
break
if allocated_blocks:
print(f"Allocated {file_name} at blocks: {allocated_blocks}")
else:
print(f"Error: Not enough contiguous space available to allocate {file_name}")

def deallocate(self, file_name, blocks):


for block in blocks:
self.blocks[block] = 0
print(f"Deallocated {file_name} from blocks: {blocks}")

def compact(self):
new_blocks = [0] * self.size
allocated_blocks = []
distance_moved = 0
new_pos = 0

for i in range(self.size):
if self.blocks[i] == 1:
allocated_blocks.append(i)

for block in allocated_blocks:


new_blocks[new_pos:new_pos+1] = [1]
distance_moved += abs(new_pos - block)
new_pos += 1

self.blocks = new_blocks

print("\nMemory layout after compaction:")


for i in range(len(self.blocks)):
if self.blocks[i] == 1:
print(f"Block {i} is allocated.")
else:
print(f"Block {i} is free.")

return distance_moved

if __name__ == "__main__":
contiguous_allocation = ContiguousAllocation(20)

# Perform allocations
contiguous_allocation.allocate("File1", 5)
contiguous_allocation.allocate("File2", 7)
contiguous_allocation.allocate("File3", 4)

# Deallocate a file
contiguous_allocation.deallocate("File2", [10, 11, 12, 13, 14, 15, 16])

# Compact memory
total_movement = contiguous_allocation.compact()
print("\nTotal movement of data during compaction:", total_movement)
class ResourceAllocationGraph:
def __init__(self, num_processes, num_resources):
self.num_processes = num_processes
self.num_resources = num_resources
self.adj_matrix = [[0] * (num_processes + num_resources) for _ in range(num_processes +
num_resources)]

def add_edge(self, process, resource):


self.adj_matrix[process][resource] = 1
def print_graph(self):
print("Resource Allocation Graph:")
for row in self.adj_matrix:
print(row)

if __name__ == "__main__":
num_processes = int(input("Enter the number of processes: "))
num_resources = int(input("Enter the number of resources: "))

rag = ResourceAllocationGraph(num_processes, num_resources)

print("Enter the allocations in the format [Process, Resource]:")


print("Note: Process and Resource indices start from 0.")

while True:
user_input = input("Enter allocation (or 'done' to finish): ")
if user_input.lower() == 'done':
break
else:
try:
process, resource = map(int, user_input.split(','))
rag.add_edge(process, num_processes + resource)
except ValueError:
print("Invalid input. Please enter allocation in the format [Process, Resource].")

rag.print_graph()
class BankersAlgorithm:
def __init__(self, available, max_claim, allocation):
self.available = available
self.max_claim = max_claim
self.allocation = allocation
self.num_processes = len(allocation)
self.num_resources = len(available)

def is_safe_state(self, request):


# Step 1: Check if the request is within the available resources
for i in range(self.num_resources):
if request[i] > self.available[i]:
print("Request exceeds available resources.")
return False

# Step 2: Check if the request can be satisfied


new_available = self.available[:]
new_allocation = [self.allocation[i][:] for i in range(self.num_processes)]
need = [[self.max_claim[i][j] - self.allocation[i][j] for j in range(self.num_resources)] for i in
range(self.num_processes)]

for i in range(self.num_resources):
new_available[i] -= request[i]
new_allocation[request[-1]][i] += request[i]

safe_sequence = []
finish = [False] * self.num_processes

while True:
found = False
for i in range(self.num_processes):
if not finish[i]:
if all(need[i][j] <= new_available[j] for j in range(self.num_resources)):
for j in range(self.num_resources):
new_available[j] += new_allocation[i][j]
finish[i] = True
safe_sequence.append(i)
found = True
break
if not found:
break

if all(finish):
print("System is in a safe state.")
print("Safe sequence:", safe_sequence)
return True
else:
print("System is in an unsafe state. Deadlock may occur.")
return False

if __name__ == "__main__":
available_resources = [3, 3, 2]
max_claim = [[7, 5, 3], [3, 2, 2], [9, 0, 2], [2, 2, 2], [4, 3, 3]]
allocation = [[0, 1, 0], [2, 0, 0], [3, 0, 2], [2, 1, 1], [0, 0, 2]]
process_id = 3
request = [1, 0, 2, process_id] # Requesting 1 of resource 1 and 2 of resource 3 for process 3

banker = BankersAlgorithm(available_resources, max_claim, allocation)


banker.is_safe_state(request)

You might also like