Sep 12, 2024

Banker's Algorithm

A resource allocation method that ensures safe process execution while preventing deadlocks.

Source Code

class BankersAlgorithm:
    def __init__(self, num_processes, num_resources):
        self.num_processes = num_processes
        self.num_resources = num_resources

        # Maximum resources required by each process
        self.max_resources = [[0] * num_resources for _ in range(num_processes)]
        # Allocation of resources to each process
        self.allocation = [[0] * num_resources for _ in range(num_processes)]
        # Available resources
        self.available = [0] * num_resources

    def input_resources(self):
        print("Enter maximum resources for each process:")
        for i in range(self.num_processes):
            self.max_resources[i] = list(map(int, input(f"Process {i} max resources: ").split()))

        print("Enter allocated resources for each process:")
        for i in range(self.num_processes):
            self.allocation[i] = list(map(int, input(f"Process {i} allocated resources: ").split()))

        print("Enter available resources:")
        self.available = list(map(int, input("Available resources: ").split()))

    def calculate_needs(self):
        self.needs = [[self.max_resources[i][j] - self.allocation[i][j] for j in range(self.num_resources)]
                       for i in range(self.num_processes)]

    def is_safe(self):
        work = self.available[:]
        finish = [False] * self.num_processes
        safe_sequence = []

        while len(safe_sequence) < self.num_processes:
            allocated = False
            for i in range(self.num_processes):
                if not finish[i] and all(self.needs[i][j] <= work[j] for j in range(self.num_resources)):
                    # Simulate allocating resources
                    for j in range(self.num_resources):
                        work[j] += self.allocation[i][j]
                    finish[i] = True
                    safe_sequence.append(i)
                    allocated = True
                    break
            if not allocated:
                print("System is not in a safe state.")
                return False, []

        print("System is in a safe state.")
        print("Safe sequence is:", safe_sequence)
        return True, safe_sequence

    def request_resources(self, process_id, request):
        print(f"Process {process_id} requests resources: {request}")

        if any(request[j] > self.needs[process_id][j] for j in range(self.num_resources)):
            print("Error: Process has exceeded its maximum claim.")
            return False

        if any(request[j] > self.available[j] for j in range(self.num_resources)):
            print("Resources not available. Process must wait.")
            return False

        # Pretend to allocate requested resources
        for j in range(self.num_resources):
            self.available[j] -= request[j]
            self.allocation[process_id][j] += request[j]
            self.needs[process_id][j] -= request[j]

        # Check for safety
        is_safe, _ = self.is_safe()

        if not is_safe:
            # Rollback
            for j in range(self.num_resources):
                self.available[j] += request[j]
                self.allocation[process_id][j] -= request[j]
                self.needs[process_id][j] += request[j]
            print("Request cannot be granted, reverting changes.")
            return False

        print("Resources allocated successfully.")
        return True

def main():
    num_processes = int(input("Enter number of processes: "))
    num_resources = int(input("Enter number of resources: "))

    bank = BankersAlgorithm(num_processes, num_resources)
    bank.input_resources()
    bank.calculate_needs()

    safe, _ = bank.is_safe()

    while True:
        process_id = int(input("Enter process ID to request resources (or -1 to exit): "))
        if process_id == -1:
            break
        request = list(map(int, input(f"Enter resource request for process {process_id}: ").split()))
        bank.request_resources(process_id, request)

if __name__ == "__main__":
    main()

Output

Enter number of processes: 5
Enter number of resources: 3

Enter maximum resources for each process:
Process 0 max resources: 7 5 3
Process 1 max resources: 3 2 2
Process 2 max resources: 9 0 2
Process 3 max resources: 2 2 2
Process 4 max resources: 4 3 3

Enter allocated resources for each process:
Process 0 allocated resources: 0 1 0
Process 1 allocated resources: 2 0 0
Process 2 allocated resources: 3 0 2
Process 3 allocated resources: 2 1 1
Process 4 allocated resources: 0 0 2

Enter available resources: 3 3 2
System is in a safe state.
Safe sequence is: 1 0 3 4 2

Enter process ID to request resources (or -1 to exit): 1
Enter resource request for process 1: 1 0 2
Process 1 requests resources: 1 0 2
Resources allocated successfully.

Enter process ID to request resources (or -1 to exit): 4
Enter resource request for process 4: 0 2 0
Process 4 requests resources: 0 2 0
Resources allocated successfully.

Enter process ID to request resources (or -1 to exit): -1