算法的核心:
一.安全性算法
安全性算法返回值为布尔类型,即调用时,如果当前系统安全,则返回true
1.初始化。.首先初始化进程的状态数组Finish[n]为false,数组Work[m]的初始值为当前系统资源的值
2.寻找可执行(未完成)的进程。用sum记录已完成进程的个数,用sum_flag记录遍历所有进程之后是否找到可执行的进程
1)if (temp.Need[i][j] > Work[j]),则flag=false,跳到下一个进程;
else (此时flag=true) {sum_flag=true,即遍历一遍至少存在一个可执行的进程;释放该进程的资源,sum++;}
3.如果sum=进程数,则所有的进程都可执行,则当前系统处于安全状态
4.如果在执行完所有进程之前,遍历一遍所有进程无法找到可执行的进程(sum_flag=false),则当前系统处于不安全状态
二.资源分配算法
1.创建临时结构体temp,初始值为banker
2.判断系统现有的资源能否满足进程的申请
1)如果一个进程申请的某类资源可以满足,则为其分配资源
2)如果一个进程申请的各种资源无法同时满足,则撤回已为其分配的资源
3)如果一个进程申请的各种资源同时满足,(强掉一下,此时系统当前的资源已经被修改)则调用安全性算法,判断是否存在安全性序列
3.返回到系统的初始状态,继续测试(即满足其他进程的申请)
完整代码:
#include <iostream>
#include<iomanip>
#include <cstdlib>
using namespace std;
#define max_m 100
#define max_n 100
/*定义数据结构*/
typedef struct
{
int Available[max_m];
int Max[max_n][max_m];
int Allocation[max_n][max_m];
int Need[max_n][max_m];
int Request[max_n][max_m];
int n, m;
}Banker;
/*资源初始化*/
void Ini_resource(Banker& banker)
{
srand(unsigned(time(0)));
//cout << "请输入进程数和资源种类:";
//cin >> banker.n >> banker.m;
banker.n = 4;
banker.m = 3;//这里按课本的实例了,如果要改,下面的输出格式(间隔)也要改
for (int i = 0; i < banker.n; i++)
{
for (int j = 0; j < banker.m; j++)
{
banker.Allocation[i][j] = rand() % 3;//当前拥有的资源为0~2
banker.Max[i][j] = rand() % 3+2;//最大的资源为2~4
banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];//需要的资源为0~4
/*随机申请资源*/
banker.Request[i][j] = rand() % 5;//申请的资源为0~4
/*判断申请资源的合法性*/
while (banker.Request[i][j] > banker.Need[i][j])
{
banker.Request[i][j] = rand() % 5;
}
/*系统现有资源只需要生成一次,这里在最后一个进程的初始化时生成*/
if (i == banker.n - 1)
{
banker.Available[j] = rand() % 5;//系统当前拥有的资源为0~4
}
}
}
}
/*打印函数*/
void print(Banker banker)
{
cout << std::left << setw(13) << "进程 " << setw(30) << "Allocation" << setw(30) << "Max" << setw(30) << "Need" << setw(30) << "Request" << setw(30) << "Available" << endl;
cout << std::left << setw(12) << "资源" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(15) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << endl;
for (int i = 0; i < banker.n; i++)
{
cout << std::left << "P" << i << setw(10) << "";
for (int j = 0; j < banker.m; j++)
cout << setw(6) << banker.Allocation[i][j];
cout << setw(10) << "";
for (int j = 0; j < banker.m; j++)
cout << setw(6) << banker.Max[i][j];
cout << setw(10) << "";
for (int j = 0; j < banker.m; j++)
cout << setw(6) << banker.Need[i][j];
cout << setw(10) << "";
for (int j = 0; j < banker.m; j++)
cout << setw(6) << banker.Request[i][j];
/*系统资源只要打印一次*/
if (i == 2)
{
cout << setw(15) << "";
for (int j = 0; j < banker.m; j++)cout << setw(6) << banker.Available[j];
}
cout << endl;
}
}
/*安全性算法*/
/*
安全性算法返回值为布尔类型,即调用时,如果当前系统安全,则返回true
1.初始化。.首先初始化进程的状态数组Finish[n]为false,数组Work[m]的初始值为当前系统资源的值
2.寻找可执行(未完成)的进程。用sum记录已完成进程的个数,用sum_flag记录遍历所有进程之后是否找到可执行的进程
1)if (temp.Need[i][j] > Work[j]),则flag=false,跳到下一个进程;
else (此时flag=true) {sum_flag=true,即遍历一遍至少存在一个可执行的进程;释放该进程的资源,sum++;}
3.如果sum=进程数,则所有的进程都可执行,则当前系统处于安全状态
4.如果在执行完所有进程之前,遍历一遍所有进程无法找到可执行的进程(sum_flag=false),则当前系统处于不安全状态
*/
bool Safety(Banker temp)//无需真实修改实参的值
{
/*初始化进程状态,起初都为false*/
bool Finish[max_n];
for (int i = 0; i < temp.n; i++)Finish[i] = false;
/*临时数组Work,初始值为Available*/
int Work[max_m];
for (int j = 0; j < temp.m; j++)Work[j] = temp.Available[j];
cout << std::left << setw(13) << "进程 " << setw(30) << "Work" << setw(30) << "Need" << setw(30) << "Allocation" << setw(30) << "Work+Allocation" << setw(30) << "Finish" << endl;
cout << std::left << setw(12) << "资源" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(15) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << endl;
/*寻找可执行进程*/
int sum = 0;
while (sum != temp.n)//当还存在未完成的进程
{
bool sum_flag = false;//判断循环一遍之后是否有可执行的进程
int i = 0;//while1循环一次就遍历一次所有的进程
/*顺序寻找可执行的进程*/
for (; i < temp.n; i++)
{
bool flag = true;//记录进程的所有条件是否被满足
if (!Finish[i])
{
/*判断单进程的满足条件*/
for (int j = 0; j < temp.m; j++)
{
if (temp.Need[i][j] > Work[j])
{
flag = false;
break;
}
}
if (flag)//如果满足单进程的所有需求
{
cout << std::left << "P" << i << setw(10) << "";
for (int j = 0; j < temp.m; j++)
cout << setw(6) << Work[j];
cout << setw(10) << "";
for (int j = 0; j < temp.m; j++)
cout << setw(6) << temp.Need[i][j];
cout << setw(10) << "";
for (int j = 0; j < temp.m; j++)
cout << setw(6) << temp.Allocation[i][j];
cout << setw(15) << "";
for (int j = 0; j < temp.m; j++)
cout << setw(6) << Work[j] + temp.Allocation[i][j];
cout << setw(15) << "" << "true" << endl;
sum_flag = true;//有可执行的进程
/*满足该进程的所有需求,即释放该进程的资源*/
sum++;//进程可完成数+1
Finish[i] = true;
for (int j = 0; j < temp.m; j++)
{
Work[j] = Work[j] + temp.Allocation[i][j];//释放资源
}
if (sum == temp.n)//所有进程都可执行
{
cout << "存在完整的安全序列,检测完毕." << endl; return true;
};
}
}
}
if (!sum_flag) { cout << "循环一遍没找到可执行的进程,新系统状态不安全" << endl; return false; }
}
}
/*资源分配算法
1.创建临时结构体temp,初始值为banker
2.判断系统现有的资源能否满足进程的申请
1)如果一个进程申请的某类资源可以满足,则为其分配资源
2)如果一个进程申请的各种资源无法同时满足,则撤回已为其分配的资源
3)如果一个进程申请的各种资源同时满足,(强掉一下,此时系统当前的资源已经被修改)则调用安全性算法,判断是否存在安全性序列
3.返回到系统的初始状态,继续测试(即满足其他进程的申请)
*/
void Div_source(Banker& banker)
{
cout << "系统的初始状态:" << endl;
print(banker);
cout << endl;
/*创建临时结构体temp,初始值为banker*/
Banker temp;
temp.m = banker.m;
temp.n = banker.n;
for (int i = 0; i < banker.n; i++)
for (int j = 0; j < banker.m; j++)
{
temp.Available[j] = banker.Available[j];
temp.Allocation[i][j] = banker.Allocation[i][j];
temp.Need[i][j] = banker.Need[i][j];
temp.Max[i][j] = banker.Max[i][j];
temp.Request[i][j] = banker.Request[i][j];
}
/*判断系统现有的资源能否满足进程的申请*/
for (int i = 0; i < banker.n; i++)
{
bool flag = false;
/*一个进程资源的分配*/
for (int j = 0; j < banker.m; j++)
{
if (banker.Request[i][j] > banker.Available[j])
{
//该进程申请的资源j系统此刻无法满足,撤回re_j<j的资源
// 跳到下一个进程
for (int re_j = 0; re_j < j; re_j++)
{
temp.Available[re_j] = banker.Available[re_j];
temp.Allocation[i][re_j] = banker.Allocation[i][re_j];
temp.Need[i][re_j] = banker.Need[i][re_j];
temp.Request[i][re_j] = banker.Request[i][re_j];
}
break;
}
/*如果一个进程申请的某类资源可以满足,则为其分配资源*/
temp.Available[j] = temp.Available[j] - banker.Request[i][j];
temp.Allocation[i][j] = temp.Allocation[i][j] + banker.Request[i][j];
temp.Need[i][j] = temp.Need[i][j] - banker.Request[i][j];
temp.Request[i][j] = 0;
if (j == banker.m - 1) flag = true;
}
/*如果系统现有的资源满足进程的申请*/
if (flag)
{
cout << "假设满足进程" << i << "申请的资源:";
for (int j = 0; j < banker.m; j++)cout << banker.Request[i][j] << " ";
cout << endl;
cout << "此时系统的状态:" << endl;
print(temp);
cout << "系统安全情况分析:" << endl;
/*调用安全性算法,判断是否要实际分配资源*/
Safety(temp);//调用安全性算法的时候,此时系统的状态已经被修改
cout << "撤回假设分配的资源,即回到系统的初始状态,继续测试" << endl;
cout << endl;
for (int yes_j = 0; yes_j < banker.m; yes_j++)
{
temp.Available[yes_j] = banker.Available[yes_j];
temp.Allocation[i][yes_j] = banker.Allocation[i][yes_j];
temp.Need[i][yes_j] = banker.Need[i][yes_j];
temp.Request[i][yes_j] = banker.Request[i][yes_j];
}
}
else
{
cout << "进程" << i << "申请的资源系统无法满足" << endl;
cout << endl;
}
}
}
int main()
{
Banker banker;
Ini_resource(banker);
Div_source(banker);
}
运行效果图