0% found this document useful (0 votes)
27 views11 pages

Notes

Uploaded by

fkpyzxz4zh
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)
27 views11 pages

Notes

Uploaded by

fkpyzxz4zh
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/ 11

Banker's Algorithm

---

Experiment Title:

Banker's Algorithm for Deadlock Avoidance

Objective:

To understand and implement the Banker's Algorithm in C++ for resource allocation and
deadlock avoidance in a multi-process environment.

Theory:

The Banker's Algorithm, developed by Edsger Dijkstra, is used in operating systems for
deadlock avoidance by managing resource allocation. This algorithm works by ensuring
that a system remains in a safe state when it allocates resources to processes. A "safe
state" means there exists a sequence in which all processes can complete their tasks
without leading to deadlock.

# Key Terminologies:

1. Safe State : A state in which all processes can be executed to completion without
causing a deadlock.

2. Max Need : Maximum demand of each process for resources.

3. Allocation : Resources currently allocated to each process.

4. Need : Resources still needed by a process to complete (Max Need - Allocation).

5. Available : Resources available in the system at a given moment.

The algorithm checks if granting a request leads to a safe state by simulating the
allocation. If it’s safe, the resources are allocated; otherwise, the request is denied.

---
Requirements:

- Basic knowledge of C++ programming.

- Understanding of deadlock concepts in Operating Systems.

Components of Banker's Algorithm:

1. Data Structures :

- `Max[i][j]`: Maximum demand of process `i` for resource `j`.

- `Allocation[i][j]`: Resources of type `j` currently allocated to process `i`.

- `Need[i][j]`: Remaining resource need for process `i` for resource `j`.

- `Available[j]`: Number of instances available of each resource type `j`.

2. Functionality :

- Request Check : Check if a process's resource request can be safely granted.

- Safety Check : Determine if the system remains in a safe state after allocation.

---

Implementation Steps:

1. Initialize matrices `Max`, `Allocation`, `Need`, and `Available`.

2. Input resource allocation and max needs for each process.

3. Calculate Need matrix by subtracting `Allocation` from `Max`.

4. Implement the safety algorithm to ensure the system remains in a safe state.

5. Implement the resource request algorithm to determine if a request can be safely


granted.

---
Sample C++ Code:

#include <iostream>

using namespace std;

const int P = 5; // Number of processes

const int R = 3; // Number of resource types

void calculateNeed(int need[P][R], int max[P][R], int allocation[P][R]) {

for (int i = 0; i < P; i++)

for (int j = 0; j < R; j++)

need[i][j] = max[i][j] - allocation[i][j];

bool isSafe(int processes[], int available[], int max[][R], int allocation[][R]) {

int need[P][R];

calculateNeed(need, max, allocation);

bool finish[P] = {0};

int safeSeq[P];

int work[R];

for (int i = 0; i < R; i++)

work[i] = available[i];

int count = 0;

while (count < P) {

bool found = false;

for (int p = 0; p < P; p++) {


if (!finish[p]) {

int j;

for (j = 0; j < R; j++)

if (need[p][j] > work[j])

break;

if (j == R) {

for (int k = 0; k < R; k++)

work[k] += allocation[p][k];

safeSeq[count++] = p;

finish[p] = 1;

found = true;

if (!found) {

cout << "System is not in a safe state.\n";

return false;

cout << "System is in a safe state.\nSafe sequence is: ";

for (int i = 0; i < P; i++)

cout << safeSeq[i] << " ";

cout << endl;

return true;

int main() {

int processes[] = {0, 1, 2, 3, 4};


int available[] = {3, 3, 2};

int max[P][R] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};

int allocation[P][R] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};

isSafe(processes, available, max, allocation);

return 0;

---

Sample Output:

System is in a safe state.

Safe sequence is: 1 3 4 0 2

---

Explanation of Code:

1. calculateNeed: Computes the `Need` matrix by subtracting `Allocation` from


`Max`.

2. isSafe: Determines if the system is in a safe state by checking if there exists a


sequence in which all processes can complete.

3. main: Initializes data and checks for a safe sequence.

---

Conclusion:

This experiment demonstrates the implementation of the Banker's Algorithm in C++. By


analyzing a system's resource allocation, it is possible to determine a safe sequence,
preventing deadlocks and ensuring smooth process execution.
---

Viva Questions:

1. Explain the significance of the Banker's Algorithm in deadlock avoidance.

2. What is a "safe state," and why is it important?

3. How does the algorithm handle resource requests from processes?

4. Can Banker's Algorithm handle dynamic resource allocation?


### Code Explanation

#### 1. **Including Libraries and Defining Constants**

```cpp

#include <iostream>

using namespace std;

const int P = 5; // Number of processes

const int R = 3; // Number of resource types

```

- **`#include <iostream>`** includes the input-output library for handling basic


console operations.

- **`P`** and **`R`** are constants representing the number of processes and
resource types. In this example, we have `5` processes and `3` types of resources.

#### 2. **Calculating the Need Matrix**

```cpp

void calculateNeed(int need[P][R], int max[P][R], int allocation[P][R]) {

for (int i = 0; i < P; i++)

for (int j = 0; j < R; j++)

need[i][j] = max[i][j] - allocation[i][j];

```

- This function calculates the **Need** matrix, which shows the remaining resources
each process requires to complete its task.
- **Formula**: `Need[i][j] = Max[i][j] - Allocation[i][j]`.

- The function takes three matrices as input: `need`, `max`, and `allocation`.

- `max[i][j]`: Maximum resources of type `j` required by process `i`.

- `allocation[i][j]`: Resources of type `j` currently allocated to process `i`.

- The result is stored in `need[i][j]`.

#### 3. **Safety Algorithm**

```cpp

bool isSafe(int processes[], int available[], int max[][R], int allocation[][R]) {

int need[P][R];

calculateNeed(need, max, allocation);

bool finish[P] = {0};

int safeSeq[P];

int work[R];

for (int i = 0; i < R; i++)

work[i] = available[i];

int count = 0;

while (count < P) {

bool found = false;

for (int p = 0; p < P; p++) {

if (!finish[p]) {

int j;

for (j = 0; j < R; j++)

if (need[p][j] > work[j])

break;
if (j == R) {

for (int k = 0; k < R; k++)

work[k] += allocation[p][k];

safeSeq[count++] = p;

finish[p] = 1;

found = true;

if (!found) {

cout << "System is not in a safe state.\n";

return false;

cout << "System is in a safe state.\nSafe sequence is: ";

for (int i = 0; i < P; i++)

cout << safeSeq[i] << " ";

cout << endl;

return true;

```

The **`isSafe`** function performs the main steps of the Banker's Algorithm.

1. **Initialize Need Matrix**: Calls `calculateNeed` to determine the `Need` matrix.

2. **Finish Array**: `finish` keeps track of completed processes. Initially, all are set to
`false`.

3. **Work Array**: A copy of the `Available` resources, representing resources


currently available.
4. **Safe Sequence**: An array `safeSeq` to store the sequence of process execution
that maintains a safe state.

#### 4. **Checking Each Process**

The algorithm checks each process to see if it can finish with the resources in the
`work` array.

1. For each process `p`:

- Check if it’s not finished (`finish[p] == false`).

- For each resource type `j`, verify if the `Need` of process `p` for resource `j` is
less than or equal to `work[j]`. If this condition fails, the process cannot finish with the
current resources, and the algorithm breaks out of the loop.

- If `j` equals `R` (all resource checks passed), the process can safely finish:

- Update `work` by adding resources allocated to process `p`.

- Mark the process as finished in the `finish` array.

- Add `p` to `safeSeq`.

- Set `found` to `true`, indicating at least one process was able to proceed in this
iteration.

2. If no process could proceed (`found` is `false`), the system is unsafe, and the
function exits, returning `false`.

3. If all processes finish successfully, the function outputs the safe sequence and
returns `true`, indicating a safe state.

#### 5. **Main Function**

```cpp

int main() {
int processes[] = {0, 1, 2, 3, 4};

int available[] = {3, 3, 2};

int max[P][R] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};

int allocation[P][R] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};

isSafe(processes, available, max, allocation);

return 0;

```

- **Processes Array**: Holds identifiers for each process.

- **Available Array**: Holds the initial count of available resources.

- **Max Matrix**: Specifies each process's maximum requirement for each resource
type.

- **Allocation Matrix**: Shows the current allocation of resources to each process.

The `main` function initializes these matrices and then calls `isSafe` to check if the
system is in a safe state. If it is, the safe sequence is displayed.

---

### Key Points to Note:

- **Safety Check**: The algorithm ensures the system remains in a safe state by only
granting requests that lead to a safe sequence.

- **Resource Request Simulation**: The `isSafe` function simulates resource requests


and verifies if they can be safely fulfilled.

- **Importance of the Safe Sequence**: A valid safe sequence ensures that all
processes can finish without causing deadlock.

You might also like