- OS - Home
- OS - Needs
- OS - Overview
- OS - History
- OS - Components
- OS - Structure
- OS - Architecture
- OS - Services
- OS - Properties
- Process Management
- Operating System Processes
- Process Control Block
- Operations on Processes
- Inter Process Communication
- Context Switching
- Multi-threading
- Scheduling Algorithms
- Process Scheduling
- Preemptive and Non-Preemptive Scheduling
- Scheduling Algorithms Overview
- FCFS Scheduling Algorithm
- SJF Scheduling Algorithm
- Round Robin Scheduling Algorithm
- HRRN Scheduling Algorithm
- Priority Scheduling Algorithm
- Multilevel Queue Scheduling
- Lottery Scheduling Algorithm
- Turn Around Time & Waiting Time
- Burst Time in SJF Scheduling
- Process Synchronization
- Process Synchronization
- Critical Section Problem
- Critical Section Synchronization
- Mutual Exclusion Synchronization
- Semaphores
- Counting Semaphores
- Mutex
- Turn Variable
- Bounded Buffer Problem
- Reader Writer Locks
- Test and Set Lock
- Peterson's Solution
- Monitors
- Sleep and Wake
- Race Condition
- OS Deadlock
- Introduction to Deadlock
- Conditions for Deadlock
- Deadlock Handling
- Deadlock Prevention
- Deadlock Avoidance (Banker's Algorithm)
- Deadlock Detection and Recovery
- Deadlock Ignorance
- Memory Management
- Memory Management
- Contiguous Memory Allocation
- Non-Contiguous Memory Allocation
- First Fit Algorithm
- Next Fit Algorithm
- Best Fit Algorithm
- Worst Fit Algorithm
- Fragmentation
- Virtual Memory
- Segmentation
- Buddy System
- Slab Allocation
- Overlays
- Paging and Page Replacement
- Paging
- Demand Paging
- Page Table
- Page Replacement Algorithms
- Optimal Page Replacement Algorithm
- Belady's Anomaly
- Thrashing
- Storage and File Management
- File Systems
- File Attributes
- Structures of Directory
- Linked Index Allocation
- Indexed Allocation
- Disk Scheduling Algorithms
- FCFS Disk Scheduling
- SSTF Disk Scheduling
- SCAN Disk Scheduling
- LOOK Disk Scheduling
- I/O Systems
- I/O Hardware
- I/O Software
- OS Types
- OS - Types
- OS - Batch Processing
- OS - Multiprocessing
- OS - Hybrid
- OS - Monolithic
- OS - Zephyr
- OS - Nix
- OS - Linux
- OS - Blackberry
- OS - Garuda
- OS - Tails
- OS - Clustered
- OS - Haiku
- OS - AIX
- OS - Solus
- OS - Tizen
- OS - Bharat
- OS - Fire
- OS - Bliss
- OS - VxWorks
- OS - Embedded
- OS - Single User
- Miscellaneous Topics
- OS - Security
- OS Questions Answers
- OS - Questions Answers
- OS Useful Resources
- OS - Quick Guide
- OS - Useful Resources
- OS - Discussion
Operating System - Deadlock Avoidance (Banker's Algorithm)
Read this chapter to learn how you can use the Banker's Algorithm to avoid a deadlock state in an operating system.
The Banker's Algorithm
The Banker's Algorithm is a deadlock avoidance algorithm that shows how to allocate resources to processes in a way that ensures that the system remains in a safe state. This works like a banker who allocates money to customers. Before allocating money to a customer, the banker must ensure that there is enough money in the bank to satisfy the maximum possible requests of all customers.
The Banker's Algorithm works in this way −
- When a new process enters the system, it must declare the maximum number of instances of each resource type that it may need.
- The OS then calculates whether allowing the request will leave the system in a safe state. If it does, the resources are allocated to the process.
- If the request would lead to an unsafe state, it is not allowed to take any other resources too. The process must wait until some resources are released by other processes.
Steps for Banker's Algorithm
The Banker's Algorithm works in two main steps −
- Safety Algorithm - Safe State Check
- Resource Request Handling
Safety Algorithm
The safety algorithm is one that determines whether or not the system is in a safe state. A safe state is one where there is at least one sequence of processes such that each process can obtain its maximum resource request and complete its execution without leading to a deadlock.
The safety algorithm works as follows −
- Initialize two vectors - Work and Finish. Set Work = Available and Finish [i] = FALSE for all processes.
- Find an index "i" such that both - Finish [i] = FALSE and Need [i] ⤠Work. If no such "i" exists, go to step 4.
- Set Work = Work + Allocation [i] and Finish [i] = TRUE. Go to step 2.
- If Finish [i] = TRUE for all "i", then the system is in a safe state.
Resource Request Handling
When a process makes a request for resources, the Banker's Algorithm checks whether granting the request will leave the system in a safe state. The steps for handling a resource request are as follows −
- If Request [i] ⤠Need [i], go to step 2. Otherwise, raise an error condition since the process has exceeded its maximum claim.
- If Request [i] ⤠Available, go to step 3. Otherwise, the process must wait until resources are available.
- Temporarily allocate the requested resources to process Pi by updating the following −
- Available = Available - Request [i]
- Allocation [i] = Allocation [i] + Request [i]
- Need [i] = Need [i] - Request [i]
- Use the safety algorithm to check if the system is in a safe state after the allocation. If it is, the request is granted. If not, roll back to the previous state and make the process wait.
Example of Banker's Algorithm
Consider a system with 5 processes (P0 to P4) and 3 resource types (A, B, C). The total resources in the system are −
- Resource A: 10 instances
- Resource B: 5 instances
- Resource C: 7 instances
The current state of the system is represented by the following matrices −
| Process | Max Matrix | Allocation Matrix | Need Matrix | ||||||
|---|---|---|---|---|---|---|---|---|---|
| A | B | C | A | B | C | A | B | C | |
| P0 | 7 | 5 | 3 | 0 | 1 | 0 | 7 | 4 | 3 |
| P1 | 3 | 2 | 2 | 2 | 0 | 0 | 1 | 2 | 2 |
| P2 | 9 | 0 | 2 | 3 | 0 | 2 | 6 | 0 | 0 |
| P3 | 2 | 2 | 2 | 2 | 1 | 1 | 0 | 1 | 1 |
| P4 | 4 | 3 | 3 | 0 | 0 | 2 | 4 | 3 | 1 |
- Max Matrix − This contains the maximum resource needed for each process to complete its task.
- Allocation Matrix − This contains the resources currently allocated to each process.
- Need Matrix − This is calculated as Max - Allocation and represents the remaining resources needed by each process.
The Available resources in the system can be calculated as −
$$\mathrm{Available}_j \;=\; \mathrm{Total}_j \;-\; \sum_{i=0}^{n-1} \mathrm{Allocation}_{i,j} \qquad\text{for } j=0,\dots,m-1$$
So, Available = (10, 5, 7) - (7, 2, 5) = (3, 3, 2)
The Available resources are then used to check if the system is in a safe state after each allocation. If a process requests resources, the Banker's Algorithm will determine if granting the request will keep the system in a safe state.
The safe sequence for this example is - p1 â p3 â p4 â p0 â p2. This means that if the processes are executed in this order, all processes can complete their tasks without leading to a deadlock.
Implementation of Banker's Algorithm
The CPP code given below shows how to implement the Banker's Algorithm for deadlock avoidance in an operating system −
#include <iostream>
using namespace std;
#define P 5 // Number of processes
#define R 3 // Number of resources
int main() {
int i, j, k;
// Available resources
int available[R] = {3, 3, 2};
// Maximum resource demand of each process
int max[P][R] = {
{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2},
{4, 3, 3}
};
// Resources currently allocated to each process
int allocation[P][R] = {
{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}
};
// Calculate the Need matrix
int need[P][R];
for (i = 0; i < P; i++) {
for (j = 0; j < R; j++) {
need[i][j] = max[i][j] - allocation[i][j];
}
}
// Initialize Finish array
bool finish[P] = {false};
// Safe sequence array
int safeSeq[P];
int count = 0;
// Banker's Algorithm
while (count < P) {
bool found = false;
for (i = 0; i < P; i++) {
if (!finish[i]) {
bool canAllocate = true;
for (j = 0; j < R; j++) {
if (need[i][j] > available[j]) {
canAllocate = false;
break;
}
}
if (canAllocate) {
for (k = 0; k < R; k++) {
available[k] += allocation[i][k];
}
safeSeq[count++] = i;
finish[i] = true;
found = true;
}
}
}
if (!found) {
cout << "System is not in a safe state." << endl;
return 0;
}
}
cout << "System is in a safe state." << endl;
cout << "Safe sequence is: ";
for (i = 0; i < P; i++) {
cout << "P" << safeSeq[i];
if (i != P - 1) cout << " -> ";
}
cout << endl;
return 0;
}
The output of the above code will be −
System is in a safe state. Safe sequence is: P1 -> P3 -> P4 -> P0 -> P2
Conclusion
The Banker's Algorithm is a method to avoid deadlocks in an operating system. It works by calculating whether granting a resource request will not change the the safe state of the system. The resources are allocated only if the calculation shows that the system will remain in a safe state. So it is important to know the maximum resource needs of each process in advance to implement the Banker's Algorithm effectively.