一、实验目的
1、进一步了解进程的并发执行。
2、加强对进程死锁的理解,理解安全状态与不安全状态的概念。
3、掌握使用银行家算法避免死锁问题。
二、基本原理
系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其它进程使用资源。如果资源分配不当,就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。
三、模块介绍
1、main()函数模块:初始化总资源、当前已分配资源和当前可用资源;
2、safe()函数模块:判断当前状态是否为安全状态;
3、Resource_Allocation()函数模块:实现资源调度算法;
4、Print()函数模块:打印对应矩阵和向量。
四、设计步骤
根据银行家算法的基本思想,首先定义并初始化所有的矩阵和向量,并进行第一次安全性检验(如果安全则继续,否则直接退出程序),再执行资源分配算法,进行安全性检验,如果模拟分配后是安全的,则允许分配,否则回滚资源分配并阻塞当前进程。
五、流程图
六、代码实现
#include<iostream>
using namespace std;
#define MaxResourse 5 //最大资源种类数量:5
#define MaxProcess 10 //最大进程总数:10
int m, n; //m类资源、n个进程
int Resourse[MaxResourse]; //资源总量向量,表示 MaxResourse 种资源的总量
int Available[MaxResourse]; //可用资源向量,表示未分配的各种可用资源数量
int Request[MaxResourse]; //资源请求向量,表示当前申请的各种资源的数量
int Claim[MaxProcess][MaxResourse]; //最大需求矩阵,表示 MaxProcess 个进程对 MaxResourse 种资源的最大需求
int Allocation[MaxProcess][MaxResourse]; //当前分配矩阵,表示 MaxProcess 个进程已分配的各种资源数
int Need[MaxProcess][MaxResourse]; //需求矩阵,表示 MaxProcess 个进程对 MaxResourse 种资源的需求
int Process[MaxProcess]; //记录安全序列
bool Allow[MaxProcess] = { false }; //记录能否为进程分配足够的资源
void PrintVector(int vector[MaxResourse]) { //打印向量
for (int i = 0; i < m; i++)
cout << vector[i] << " ";
cout << endl;
}
void PrintMatrix(int matrix[MaxProcess][MaxResourse]) { //打印矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
}
bool safe() {
int i, j, k; //循环变量
int count = 0; //记录已完成分配的进程数(位置)
int WorkVector[MaxResourse]; //可用资源向量的拷贝,用于模拟测试安全算法
for (i = 0; i < m; i++)
WorkVector[i] = Available[i]; //拷贝
for (i = 0; i < n; i++) { //i相当于一个工作指针,扫描进程队列
if (Allow[i])
continue; //跳过已完成工作的进程
else {
for (j = 0; j < m; j++) {
if (Need[i][j] > WorkVector[j])
break; //跳过无法满足需求的进程
}
if (j == m) { //所有种类的资源都满足当前进程的需求
Allow[i] = true; //进程获取资源并完成工作
for (k = 0; k < m; k++)
WorkVector[k] += Allocation[i][k]; //释放当前进程占用的所有资源
Process[count++] = i;
i = -1; //将工作指针i置于进程队列的队首,准备下一次扫描
}
else //某个(些)资源不足以分配,则取消当前进程的分配,扫描下一个进程
continue;
}
if (count == n) { //所有进程都完成工作
cout << "A security sequence currently exists:" << endl;
for (i = 0; i < n; i++) {
if (i != n - 1)
cout << Process[i] << "—>";
else
cout << Process[i] << endl;
}
return true; //安全状态
}
}
cout << "System insecurity!" << endl;
return false; //不安全状态
}
void Resource_Allocation() {
int number; //进程编号
bool flag = true; //标识前两种异常情况
cout << "Need:" << endl;
PrintMatrix(Need);
cout << "Resourse:" << endl;
PrintVector(Resourse);
cout << "Available:" << endl;
PrintVector(Available);
while (true) {
for (int i = 0; i < n; i++)
Allow[i] = false; //初始化判断数组,默认开始为全部不允许分配
cout << "Please enter the process number for applying for the resource:";
cin >> number;
cout << "Please enter the number of each resource required by this process:";
for (int i = 0; i < m; i++)
cin >> Request[i];
for (int i = 0; i < m; i++) {
if (Request[i] > Need[number][i]) { //请求资源量多于需求资源量
cout << "The requested resource exceeded the maximum requirement!" << endl;
flag = false;
break;
}
else if (Request[i] > Available[i]) { //请求资源量多于当前可用资源量
cout << "The request exceeds the number of available resources!" << endl;
flag = false;
break;
}
}
if (!flag) {
cout << "Do you want to continue allocating resources(1 -> Yes / 0 -> No)?";
cin >> number;
if (number == 0)
break;
else
continue;
}
for (int i = 0; i < m; i++) { //模拟分配
Available[i] -= Request[i];
Allocation[number][i] += Request[i];
Need[number][i] -= Request[i];
}
if (safe()) { //安全状态
cout << "Agree to allocate resources!" << endl;
int sum = 0;
for (int i = 0; i < m; i++)
sum += Need[number][i];
if (sum == 0) { //进程可以开始完成任务并释放占用资源
for (int i = 0; i < m; i++)
Available[i] += Allocation[number][i];
} //进程未获得足够的资源,不释放占用资源
}
else { //不安全状态
cout << "Refuse to allocate resources!" << endl;
for (int i = 0; i < m; i++) { //撤回模拟分配
Available[i] += Request[i];
Allocation[number][i] -= Request[i];
Need[number][i] += Request[i];
}
}
cout << "Need:" << endl;
PrintMatrix(Need);
cout << "Resourse:" << endl;
PrintVector(Resourse);
cout << "Available:" << endl;
PrintVector(Available);
cout << "Do you want to continue allocating resources(1 -> Yes / 0 -> No)?";
cin >> number;
if (number == 0)
break;
}
}
int main() {
cout << "************************Banker's Algorithm**************************" << endl;
cout << "Please enter the number of resource types (not more than 5):";
cin >> m;
cout << "Please enter the total number of processes (not more than 10):";
cin >> n;
cout << "Please enter the maximum amount of each resource required by each process (Claim):" << endl;
for (int i = 0; i < n; i++) //初始化最大需求矩阵
for (int j = 0; j < m; j++)
cin >> Claim[i][j];
cout << "Please enter the number of resources for each resource that each process has allocated (Allocation):" << endl;
do { //初始化当前分配矩阵
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> Allocation[i][j];
Need[i][j] = Claim[i][j] - Allocation[i][j]; //同步计算需求矩阵
if (Need[i][j] < 0)
count++; //记录分配错误次数
}
}
if (count > 0) //输出错误次数并重新初始化当前分配矩阵
cout << count << " assignment error, please re-enter (Allocation):" << endl;
else
break;
} while (true);
cout << "Please enter the number of available resources for each resource (Available):" << endl;
for (int i = 0; i < m; i++) //初始化可用资源向量
{
cin >> Available[i];
int sum = 0;
for (int j = 0; j < n; j++)
sum += Allocation[j][i];
Resourse[i] = sum + Available[i]; //同步计算资源总量向量
}
//cout << endl << "Claim:" << endl;
//PrintMatrix(Claim);
//cout << "Allocation:" << endl;
//PrintMatrix(Allocation);
//cout << "Need:" << endl;
//PrintMatrix(Need);
//cout << "Resourse:" << endl;
//PrintVector(Resourse);
//cout << "Available:" << endl;
//PrintVector(Available);
//cout << endl;
bool start = safe(); //判断初始状态是否安全
cout << endl;
if (start) {
Resource_Allocation(); //分配资源
return 0;
}
else
return 0;
}
七、实验结果与分析
1、初始化
初始化Claim矩阵、Allocation矩阵和Available向量,经安全性检验后给出安全序列(1->3->0->2->4)和当前的Need矩阵和Available向量;
2、允许分配(进程仍未工作)
1号进程申请资源0,1,0,经过安全性检验,允许分配,调整Need矩阵和Available向量;
3、拒绝分配
0号进程申请资源0,2,0,经过安全性检验,不允许分配,回滚进程。
4、允许分配(进程完成工作)
1号进程申请资源0,1,0,经过安全性检验,允许分配,且1号进程已得到所需资源并完成工作,因此将1号进程占有的资源释放回Available向量。
5、分配完成
按照安全序列分配完成,回收所有资源,且资源总量刚好等于可分配资源量,Need矩阵为零矩阵,程序结束。