银行家算法
1.实验目的
死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。
2.实验内容与要求
设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。
系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析;
1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。
2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。
3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。
4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。
上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j);
3.流程图与模块调用
4.实验分析
本次算法实验流程如下:
- 已经存在,系统全部资源、各个进程所请求最大资源、系统所剩资源、各个进程已经分配的资源。可以得到进程剩余所需最大资源。
- 输入进程i,输入该进程想要请求的各类资源,执行银行家算法,在银行家算法中尝试找到,如果将该进程所请求资源分配给该进程的话,是否存在安全序列(安全性算法),如果存在安全序列,则可以分配该进程资源。如果不存在,则拒绝分配给该进程资源。
5.运行情况
6.实验体会
银行家算法,采取的是避免死锁,在进程运行中进行处理死锁,需要动态的模拟整个系统分配资源的过程,其关键点在于如果将进程所求资源分配给该进程,是否能够找到一个安全序列,(这个过程只是操作系统内部模拟,并不是真的分配),如果能找到安全序列,即可分配;若未找到,则不可分配。
代码
#include<iostream>
#include<vector>
using namespace std;
int m;//资源
vector<int> all;//各类资源总数
int n;//进程数
vector<vector<int>> max_r;//最大需求向量
vector<vector<int>> need;//所需资源
vector<int>av;//空闲资源
vector<vector<int>> allocation;//已分配
vector<int>sign;
vector<vector<int>>work;
vector<vector<int>>workAll;
//记录成功的安全序列,并定义工作矩阵和可用资源矩阵
//安全性算法
int safe(vector<int> Av, vector<vector<int>> avali, vector<vector<int>> allo) {
int i = 0, j = 0, p = 0, q = 0;
int Work[] = { 0,0,0,0,0 }, Finish[] = { 0,0,0,0,0 };
for (int r = 0; r < m; r++) //将可用资源数目赋给工作向量
Work[r] = Av[r];
while (i < n) {
if (Finish[i] == 0) {
//满足条件释放资源,并从头开始扫描进程集合
while (j < m && need[i][j] <= Work[j])
j++;
if (j == m) {
for (int k = 0; k < m; k++) {
work[i][k] = Work[k];
Work[k] = Work[k] + allo[i][k];
workAll[i][k] = Work[k];
}
Finish[i] = 1;
sign[p] = i; //保存安全序列
i = -1; p++;
}
}
j = 0; i++;
}
for (int i = 0; i < n; i++) {
if (Finish[i] == 1)
q++; //记录个数
}
return q; //返回个数
}
int Banker(int i, vector<vector<int>> request) {
for (int j = 0; j < m; j++) {
if (request[i][j] > need[i][j]) {
cout << "所需资源数超出其宣布的最大值!" << endl;
return 0;
}
else if (request[i][j] > av[j]) {
cout << "无足够资源,p[" << i << "]需等待!" << endl;
return 0;
}
}
//尝试为进程分配资源
for (int j = 0; j < m; j++) {
av[j] = av[j] - request[i][j];
allocation[i][j] = allocation[i][j] + request[i][j];
need[i][j] = need[i][j] - request[i][j];
}
//执行安全性算法
int p = safe(av, need, allocation);
cout << endl;
if (p == n) {//表示此时刻安全
cout << "是安全状态,可以为 " << i << "分配资源!" << endl;
}
else {
//分配过的资源还给系统
for (int j = 0; j < m; j++) {
av[j] = av[j] + request[i][j];
allocation[i][j] = allocation[i][j] - request[i][j];
need[i][j] = need[i][j] + request[i][j];
}
cout << "不是安全状态,不能为 " << i << "分配资源!" << endl;
}
return p;
}
//打印执行序列
void Print(int result) {
if (result == n) {
cout << " 进程资源情况" <<'\t' << " Need" << '\t' << " Allocation" << '\t'<<'\t' << " 工作时剩余资源" << '\t'<<'\t' << " 是否完成";
cout << endl;
for (int i = 0; i < n; i++) {
cout << " " << "P[" << sign[i] << "] " << '\t';
for (int j = 0; j < m; j++)
cout << need[sign[i]][j] << " ";
cout << '\t' << '\t';
for (int j = 0; j < m; j++)
cout << allocation[sign[i]][j] << " ";
cout << '\t' << '\t';
for (int j = 0; j < m; j++)
cout << workAll[sign[i]][j] << " ";
cout << '\t' << '\t';
cout << "true" << endl;
}
cout << endl << "找到安全序列{P[" << sign[0] << "]";
for (int j = 1; j < n; j++) {
cout << ", P[" << sign[j] << "]";
}
cout << "}" << endl;
}
else {
cout << " 进程资源情况 " <<'\t' << " Allocation" <<'\t' << " Need" <<'\t'<< " Available";
cout << endl;
for (int k = 0; k < n; k++) {
cout << '\t' << "P[" << k << "]" << '\t' << '\t';
for (int j = 0; j < m; j++)
cout << allocation[k][j] << " ";
cout << '\t' << '\t';
for (int j = 0; j < m; j++)
cout << need[k][j] << " ";
cout << '\t' << '\t';
if (k == 0) {
for (int j = 0; j < m; j++)
cout << av[j] << " ";
}
cout << endl;
}
}
}
int main()
{
cout << "输入资源数" << endl;
cin >> m;
cout << "输入各类资源数" << endl;
for (int i = 0; i < m; i++)
{
int l;
cin >> l;
all.push_back(l);
av.push_back(l);
}
cout << "输入进程数" << endl;
cin >> n;
cout << "输入各类资源最大需求量" << endl;
allocation.resize(n);
sign.resize(n);
//max_r.resize(n);
for (int i = 0; i < n; i++)
{
vector<int> now;
for (int j = 0; j < m; j++)
{
allocation[i].push_back(0);
int l;
cin >> l;
if (l > all[j])
{
cout << "超出系统最大资源,请重新输入" << endl;
j--;
}
else
{
now.push_back(l);
}
}
max_r.push_back(now);
}
need.resize(n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
need[i].resize(m);
need[i][j] = max_r[i][j];
}
}
int i;
char N='a';
vector<vector<int>> request;
request.resize(n);
work.resize(n);
workAll.resize(n);
for (int i = 0; i < n; i++)
{
request[i].resize(m);
work[i].resize(m);
workAll[i].resize(m);
}
while (N != 'q')
{
cout << endl << "请输入请求资源" << endl;
cout << "进程i=:";
cin >> i;
cout << "各类资源数量: ";
for (int j = 0; j < m; j++)
cin >> request[i][j];
cout << endl;
int bank = Banker(i, request);
cout << endl << "资源分配表:" << endl;
Print(bank);
cout << endl;
cout << "输入'q'退出" << endl;
cin >> N;
}
}