前言
操作系统在对资源进行分配的时候会出现一种资源的争抢,为了避免在资源争抢的时候出现死锁现象引入了银行家算法。避免死锁
当进程提出资源分配请求时,OS先判断满足本次请求会不会导致系统不安全状态。如果是,拒绝分配资源并阻塞进程;否则分配资源。
安全状态:如果OS能够找到某种进程顺序(如Pi、Pj、Pk、…Pn),使得给每个进程分配所有需要的资源后,能够依次顺利执行结束并释放资源,那么称为系统处在安全状态;否则(即不存在这种顺序)称为系统处在不安全状态。
银行家算法的数据结构
可利用资源向量Available:m列,如果Available(i)=k,则表示现有Ri类资源k个。
最大需求矩阵Max:n*m矩阵,如果Max(i,j)=k,则表示进程i需要Rj类资源的最大数目为k个。
分配矩阵Allocation:n*m矩阵,如果Allocation(i,j)=k,则表示进程i已经获得j类资源k个。
需求矩阵Need:n*m矩阵,如果Need(i,j)=k,则表示进程i仍需要j类资源k个。
安全性算法的数据结构
工作向量Work:m列,表示m类可用资源个数,初始值为Available。
进程可否运行结束向量Finish:n列,如果Finishi(i)=true,则表示进程i可以得到足够资源并运行结束。初始值全为false。
算法思路
这里在模拟实现的过程当中主要用到了两个函数初始化函数init和判断安全性算法的safe函数,初始化过程负责对数据输入的存储工作,主要用到了二维数组,其次核心算法safe是如何做到判断安全序列的呢,我在这里主要用到了计数的思路,如果每个进程即每行数组为一个进程都符合资源分配请求,则将其状态极为TRUE ,如果为false跳过本次循环,根据排列组合原理,最外层的循环执行进程个数次就能遍历到所有进程间排列的组合顺序,所以最外层while循环只要循环进程个数次即可。
完整实现代码
#include <iostream>
using namespace std;
const int nRow = 500;
const int nColumn = 500;
int Max[nRow][nColumn];//资源最大需求矩阵
int Allocation[nRow][nColumn];//已分配资源矩阵
int Need[nRow][nColumn];//需要资源矩阵
int BeginSource[nColumn];//最开始各种资源的数量
int Available[nColumn];//当前可用各类资源数量
int Requset[nColumn];//提出资源请求个数
int safeOrder[nRow];//安全序列
int nSource;
int nPortNum;
int iTime = 0;//系统时刻
void show()
{
/*显示用户已经输入的数据*/
cout << "------------Allocation-----------------" << endl;
for (int i = 0; i < nPortNum; i++)
{
cout << "port" << i << "\t";
for (int j = 0; j < nSource; j++)
{
cout << Allocation[i][j] << "\t";
}
cout << endl;
}
cout << "------------Need-----------------------" << endl;
for (int i = 0; i < nPortNum; i++)
{
cout << "port" << i << "\t";
for (int j = 0; j < nSource; j++)
{
cout << Need[i][j] << "\t";
}
cout << endl;
}
cout << endl;
cout << "---------------------------------------" << endl;
}
void Init()//初始化函数
{
cout << "请输入资源种类数" << endl;
cin >> nSource;
cout << "请输入进程数量" << endl;
cin >> nPortNum;
if (nSource > 500|| nPortNum >500)
{
cout << "资源种类或进程数量过多,请控制在500以内" << endl;
return;
}
cout << "MAX请输入现有各资源最大需求数量" << nPortNum<<"*"<<nSource<<"的矩阵"<<endl;
for (int i = 0; i < nPortNum;i++)
{
for (int j = 0; j < nSource;j++)
{
cin >> Max[i][j];
}
}
cout << "ALLOCATION请输入已经分配各个资源的数量" << nPortNum << "*" << nSource << "的矩阵" << endl;
start:
for (int i = 0; i < nPortNum; i++)
{
for (int j = 0; j < nSource; j++)
{
cin >> Allocation[i][j];
if (Allocation[i][j]>Max[i][j])
{
cout << "已分配的资源数量大于最大需求量,请重新分配" << endl;
goto start;
}
}
}
//计算Need矩阵
for (int i = 0; i < nPortNum; i++)
{
for (int j = 0; j < nSource; j++)
{
Need[i][j] = Max[i][j] - Allocation[i][j];
}
}
//计算当前可用资源数量Available
for (int i = 0; i < nPortNum; i++)
{
for (int j = 0; j < nSource; j++)
{
Available[j] += Allocation[i][j];
}
}
cout << "请输入各种资源开始的数量" << nSource << "列" << endl;
begin:
for (int i = 0; i < nSource; i++)
{
cin >> BeginSource[i];
if (BeginSource[i] < Available[i])
{
cout << "第"<<i<<"个资源开始资源数量个数太少,请重新输入" << endl;
goto begin;
}
}
for (int i = 0; i < nSource; i++)
{
Available[i] = BeginSource[i] - Available[i];
}
}
//安全性算法,计算此刻状态是否安全
bool Safe()
{
int Work[nColumn];
bool Finish[nColumn];
//将work工作向量初始化
for (int i = 0; i < nSource;i++)
{
Work[i] = Available[i];
}
//初始化finish全为false
for (int i = 0; i < nPortNum; i++)
{
Finish[i] = false;
}
int nCount = 0;
int k = nPortNum;
while (k--)//看工作向量是否操作了nSource次
{
for (int i = 0; i < nPortNum; i++)
{
int iCount = 0;//计数
int iNum = 0;
for (int j = 0; j < nSource; j++)
{
//所有资源Need都大于工作向量,则不安全
if (Need[i][j] <= Work[j])
{
iNum++;
}
}
if (iNum == nSource)//该进程满足
{
if (Finish[i] == true)
{
continue;
}
for (int j = 0; j < nSource; j++)
{
Work[j] += Allocation[i][j];
}
safeOrder[nCount] = i;
Finish[i] = true;
if (nPortNum == ++nCount)
{
return true;
}
}
}
}
return false;
}
//银行家算法
void BankSort()
{
int n;
show();
a:
cout << "请输入此刻哪个进程请求申请资源" << endl;
cin >> n;
if (n >= nPortNum)
{
cout << "没有这个进程号";
goto a;
}
cout << "请输入每类资源的请求个数" << endl;
for (int i = 0; i < nSource; i++)
{
mis:
cin >> Requset[i];
if (Requset[i] > Need[n][i ])
{
cout << "出错,申请资源大于需要资源,请重新输入"<<endl;
goto mis;
}
if (Requset[i] > Available[i])
{
//进程pi阻塞,返回
cout << "出错,申请资源大于现有资源,请重新输入" << endl;
goto mis;
}
}
for (int i = 0; i < nSource; i++)
{
Available[i] -= Requset[i];
Allocation[n][i] += Requset[i];
Need[n][i] -= Requset[i];
}
//调用安全性算法,计算此刻系统状态是否安全
if (Safe())
{
char c;
cout << "T"<<iTime<<"时刻系统安全安全序列为" <<" ";
for (int i = 0; i < nPortNum;i++)
{
if (i == nPortNum-1)
{
cout << safeOrder[i] << " ";
break;
}
cout <<safeOrder[i]<<"-->";//安全序列
}
cout << "是否继续调度按键盘任意键继续" << endl;
cin >> c;
if (c >= 0||c <= 127)
{
iTime++;
BankSort();
}
}
else
{
//此时资源分配状态不安全,恢复数据到未分配状态
for (int i = 0; i < nSource; i++)
{
Available[i] += Requset[i];
Allocation[n][i] -= Requset[i];
Need[n][i] += Requset[i];
}
char c;
cout << "T" << iTime << "时刻系统不安全不能分配任意键继续" << endl;
cin >> c;
if (c >= 0 || c <= 127)
{
BankSort();
}
}
}
int main()
{
Init();
BankSort();
system("pause");
return 0;
}