Experiment 3 banker algorithm

Keywords: Algorithm data structure

Experiment 3 deadlock avoidance algorithm of process

1, Experimental purpose

According to the idea of banker algorithm, write a program to solve the deadlock problem of concurrent processes.

2, Background knowledge

This experiment requires the design and implementation of banker algorithm. Banker algorithm is a classic deadlock avoidance algorithm. Its core idea is: the process dynamically applies for resources. Each time the system applies for resources, the system executes the security state check algorithm to judge whether the application will cause the system to be in an unsafe state. If it is not secure, the process will be blocked; If it is safe, the resource allocation is completed.

The idea of security state checking algorithm is to find a security sequence so that all processes can be executed. If found, it is in a safe state, otherwise it is unsafe.

3, Experiment contents and steps

Deadlock avoidance algorithm of process. Write a program to simulate the banker algorithm and solve the process deadlock problem.

Clion is used to realize the above program design and debugging operations, input the corresponding resource request according to the prompt, and provide a certain prompt box for the success of the algorithm operation.

Be familiar with the deadlock problem of the process by reading and analyzing the experimental program.

4, Tools / preparations

Before starting this experiment, review the relevant contents of the textbook

The following preparations need to be made:

  • A computer running the Windows 11 operating system
  • Clion is installed on your computer

5, Experimental process

(1) Data structure

struct state{
    int resource[m];
    int available[m];
    int claim[n][m];
    int alloc[n][m];
    int need[n][m];
};
state bank;

(2) Initialization status read in:

This experiment takes the following data as the test data;

9 3 6
0 1 1
3 2 2
6 1 3
3 1 4
4 2 2
1 0 0
6 1 2
2 1 1
0 0 2
void init_input(){
//    Cout < < "input process resource:";
    for(int i = 0; i < m; i++){
        cin >> bank.resource[i];
    }
//    Cout < < "enter currently available resources:";
    for(int i = 0; i < m; i++){
        cin >> bank.available[i];
    }
//    Cout < < "enter the maximum number of resources required by the process:";
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> bank.claim[i][j];
        }
    }
//    Cout < < "input process has obtained the maximum number of resources:";
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> bank.alloc[i][j];
        }
    }
    //Calculate need
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            bank.need[i][j] = bank.claim[i][j] - bank.alloc[i][j];
        }
    }
}

(3) Determine whether it is safe

boolean safe(){
    int Available[m];
    //Array for temporary calculation
    for(int i = 0; i < m; i++)
        Available[i] = bank.available[i];
    vector<int> flags;
    while(true){
        int temp = flags.size();
        for(int i = 0; i < n; i++){
            if(count(flags.begin(), flags.end(), i) > 0){
                continue;
            }
            boolean flag = true;
            for(int j = 0; j < m; j++){
                if(bank.need[i][j] <= Available[j]){
                    continue;
                }
                else{
                    flag = false;
                    break;
                }
            }
            if(flag){
                //The process meets the criteria
                flags.push_back(i);
                cout << "release:" << i + 1<< endl;
                for(int j = 0; j < m; j++){
                    //Release resources after the process runs
                   Available[j] += bank.claim[i][j];
                }
            }
        }
        if(flags.size() == temp) {
            if(flags.size() == n){
                return true;
            }
            else{
                return false;
            }
            break;
        }
    }
}
int main(){
    init_input();
    if(safe()){
        cout << "safe\n";
    }
    else{
        cout << "unsafe\n";
    }
}

First, a vector array is used to record the number of completed processes. If the traversed process has been completed, it will be skipped. If the existing resources meet the resources still needed by a process, the resources will be allocated to the process. After completing the process, release all the resources occupied by the process and continue to the next process.

Until all traversals are completed, no number is added to the vector array, indicating that the result has been determined. If the size of the array is equal to the number of processes, it indicates that it is in a safe state, that is, all processes can run normally.

(4) Complete source code:

#include <cstdlib>
#include <windows.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
const int n = 4;//Number of processes
const int m = 3;//Number of resources

struct state{
    int resource[m];
    int available[m];
    int claim[n][m];
    int alloc[n][m];
    int need[n][m];
};
state bank;
void init_input(){
//    Cout < < "input process resource:";
    for(int i = 0; i < m; i++){
        cin >> bank.resource[i];
    }
//    Cout < < "enter currently available resources:";
    for(int i = 0; i < m; i++){
        cin >> bank.available[i];
    }
//    Cout < < "enter the maximum number of resources required by the process:";
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> bank.claim[i][j];
        }
    }
//    Cout < < "input process has obtained the maximum number of resources:";
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> bank.alloc[i][j];
        }
    }
    //Calculate need
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            bank.need[i][j] = bank.claim[i][j] - bank.alloc[i][j];
        }
    }
}
boolean safe(){
    int Available[m];
    for(int i = 0; i < m; i++)
        Available[i] = bank.available[i];
    vector<int> flags;
    while(true){
        int temp = flags.size();
        for(int i = 0; i < n; i++){
            if(count(flags.begin(), flags.end(), i) > 0){
                continue;
            }
            boolean flag = true;
            for(int j = 0; j < m; j++){
                if(bank.need[i][j] <= Available[j]){
                    continue;
                }
                else{
                    flag = false;
                    break;
                }
            }
            if(flag){
                //The process meets the criteria
                flags.push_back(i);
                cout << "release:" << i + 1<< endl;
                for(int j = 0; j < m; j++){
                    //Release resources after the process runs
                   Available[j] += bank.claim[i][j];
                }
            }
        }
        if(flags.size() == temp) {
            if(flags.size() == n){
                return true;
            }
            else{
                return false;
            }
            break;
        }
    }
}
int main(){
    init_input();
    if(safe()){
        cout << "safe\n";
    }
    else{
        cout << "unsafe\n";
    }
}

(5) Operation results

6, Experimental summary

Through the experiment of banker algorithm and the programming of banker algorithm, we have a deeper understanding of the operation mechanism of banker algorithm in dynamic deadlock avoidance.

Posted by travelbuff on Tue, 02 Nov 2021 17:59:15 -0700