#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define MAXSIZE 10
int n, m;//n是进程数,m是资源数
typedef struct{
int Max[MAXSIZE][MAXSIZE];
int Allocation[MAXSIZE][MAXSIZE];
int Need[MAXSIZE][MAXSIZE];
int program;
int resource;
int Available[MAXSIZE];
}BANK;
//输入条件
void init(BANK &banker){
printf("进程数:");
scanf("%d", &n);
printf("资源数:");
scanf("%d", &m);
banker.program = n; banker.resource = m;
printf("可利用资源:");
for (int i = 0; i < banker.resource; i++)
scanf("%d", &banker.Available[i]);
printf("最大需求矩阵:\n");
for (int i = 0; i < banker.program; i++){
printf("进程P%d:", i);
for (int j = 0; j < banker.resource; j++){
scanf("%d", &banker.Max[i][j]);
}
}
printf("分配矩阵:\n");
for (int i = 0; i < banker.program; i++){
printf("进程P%d:", i);
for (int j = 0; j < banker.resource; j++){
scanf("%d", &banker.Allocation[i][j]);
//需求矩阵
banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];
//还剩的可利用资源
banker.Available[j] -= banker.Allocation[i][j];
}
}
return;
}
//展示当前资源分配表
void shownow(BANK banker){
printf("当前时刻资源分配表\n进程 Max Allocation Need Available\n");//5,8,8,8
int pause = 11 - banker.resource * 2;//空格,美观的的,没用
for (int i = 0; i < banker.program; i++){
printf("P%d ", i);//空格7个
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Max[i][j]);
for (int j = 0; j < pause;j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Allocation[i][j]);
for (int j = 0; j < (pause+7); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Need[i][j]);
if (i == 0){
for (int j = 0; j < (pause + 1); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Available[j]);
}
printf("\n");
}
}
//展示当前的安全序列
void showSafe(int *safe, int Work[], BANK banker){
printf("当前时刻安全序列\n进程 Work Need Allocation Work+Allocation");
int t = banker.program,k=0;
int pause = 12 - banker.resource * 2;//空格,美观的的,没用
for (int i = 0; i < banker.resource; i++)
Work[i] = banker.Available[i];
int temp;
while (t--){
temp = *(safe + k++);//进程号
printf("\nP%d ", temp);//空格7个
for (int j = 0; j < banker.resource; j++)
printf("%d ", Work[j]);
for (int j = 0; j < pause; j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Need[temp][j]);
for (int j = 0; j < pause; j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++){
printf("%d ", banker.Allocation[temp][j]);
Work[j] += banker.Allocation[temp][j];
}
for (int j = 0; j < (pause+6); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", Work[j]);
}
printf("\n");
return;
}
//比较a[]<=b[]是否都满足,多处应用到
bool compare(int a[], int b[]){
for (int i = 0; i < m; i++){
if (a[i]>b[i])return false;
}
return true;
}
//是否所有Finish[i]=true都满足
bool comp(bool a[]){
for (int i = 0; i < n; i++)
if (!a[i])return false;
return true;
}
//分配
void GiveTo(BANK &banker,int pro[],int pro_id){
for (int i = 0; i < banker.resource; i++){
banker.Available[i] -= pro[i];
banker.Allocation[pro_id][i] += pro[i];
banker.Need[pro_id][i] -= pro[i];
}
return;
}
//取消分配
void GiveOut(BANK &banker, int pro[], int pro_id){
for (int i = 0; i < banker.resource; i++){
banker.Available[i] += pro[i];
banker.Allocation[pro_id][i] -= pro[i];
banker.Need[pro_id][i] += pro[i];
}
return;
}
//判断是否有进程达到最大需求,有就释放给它的资源,返回释放的进程号
int finishdoult(BANK &banker){
int fh = -1;
//判断是否有进程达到最大需求,fh记录进程号
for (int i = 0; i < banker.program; i++){
if (banker.Need[i][0] == 0){
int j;
for (j = 1; j < banker.resource; j++)
if (banker.Need[i][j])break;
if (j == banker.resource){
fh = i; break;
}
}
}
if (fh == -1)return fh;
for (int i = 0; i < banker.resource; i++){
banker.Need[fh][i] = banker.Max[fh][i];
banker.Allocation[fh][i] = 0;
banker.Available[i] += banker.Max[fh][i];
}
return fh;
}
//只要有满足条件的执行即可,毕竟执行完可利用的资源只会变多
//安全性算法(银行家算法的步骤(4))
bool Savedoult(BANK banker,int *&safe){
//3.1设置两个向量
int Work[MAXSIZE],k=0;//k是保存安全序列的下标
for (int i = 0; i < banker.resource; i++)
Work[i] = banker.Available[i];
bool Finish[MAXSIZE] = { false };
//3.2:找一个满足条件的
for (int i = 0; i < banker.program; i++){
//找到,执行3.3
if (!Finish[i] && compare(banker.Need[i], Work)){
for (int j = 0; j < banker.resource; j++)
Work[j] += banker.Allocation[i][j];
Finish[i] = true;
*(safe+k++) = i;//存入安全序列
i = -1;//找到一个之后再从0开始循环(循环结束会++所以要设-1)
}
//没找到,执行3.4
else{
if (!comp(Finish))continue;
//如果都满足了即安全,展示安全序列并返回true
showSafe(safe, Work, banker);
return true;
}
}
//找不到安全序列则不安全
return false;
}
//银行家算法
void banksafe(BANK &banker,int *safe){
//步骤(0)请求(这里默认输入进程-1则退出)
int pro_id, pro[MAXSIZE];
printf("\n(-1则退出)进程:");
cin >> pro_id;
while (pro_id != -1){
if (pro_id < 0 || pro_id >= banker.program){
printf("超出进程数量限制\n进程:");
cin >> pro_id;
continue;
}
printf("进程P%d的请求变量:", pro_id);
for (int i = 0; i < banker.resource; i++)
scanf("%d", &pro[i]);
//步骤(1)
if (!compare(pro, banker.Need[pro_id])){
printf("超出它所宣布的最大值\n进程:");
cin >> pro_id;
continue;
}
//步骤(2)
if (!compare(pro, banker.Available)){
printf("尚无足够资源,需等待\n进程:");
cin >> pro_id;
continue;
}
//步骤(3)试探的分配
GiveTo(banker, pro, pro_id);
//步骤(4)安全性算法
if (Savedoult(banker, safe)){//若安全,正式分配,本次分配完成,输出安全序列和分配过后的资源分配表
printf("安全\n安全序列:");
for (int i = 0; i < banker.program; i++)
printf("%d ", *(safe + i));
printf("\n");
int fh = finishdoult(banker);//是否有运行完毕的进程
if (fh != -1){
printf("进程P%d已运行完成,释放出分配给它的资源\n",fh);
}
shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
printf("\n");
}
else{//若不安全,恢复原来的资源分配状态,等待该进程,执行其他的申请
printf("不安全\n");
GiveOut(banker, pro, pro_id);//取消分配
}
//步骤(0)请求
printf("\n进程:");
cin >> pro_id;
}
return;
}
int main(){
BANK banker;
init(banker);
//判断当前时刻是否安全
int *safe=(int*)malloc(n*sizeof(int));
if (Savedoult(banker, safe)){
printf("安全\n安全序列:");
for (int i = 0; i < banker.program; i++)
printf("%d ", *(safe + i));
int fh = finishdoult(banker);//是否有运行完毕的进程
if (fh != -1){
printf("进程P%d已运行完成,释放出分配给它的资源\n", fh);
}
shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
printf("\n");
}
else
printf("不安全\n");
banksafe(banker, safe);
system("PAUSE");
return 0;
}
0.结构体
#define MAXSIZE 10
int n, m;//n是进程数,m是资源数
typedef struct{
int Max[MAXSIZE][MAXSIZE];
int Allocation[MAXSIZE][MAXSIZE];
int Need[MAXSIZE][MAXSIZE];
int program;
int resource;
int Available[MAXSIZE];
}BANK;
1.输入条件
//输入条件
void init(BANK &banker){
printf("进程数:");
scanf("%d", &n);
printf("资源数:");
scanf("%d", &m);
banker.program = n; banker.resource = m;
printf("可利用资源:");
for (int i = 0; i < banker.resource; i++)
scanf("%d", &banker.Available[i]);
printf("最大需求矩阵:\n");
for (int i = 0; i < banker.program; i++){
printf("进程P%d:", i);
for (int j = 0; j < banker.resource; j++){
scanf("%d", &banker.Max[i][j]);
}
}
printf("分配矩阵:\n");
for (int i = 0; i < banker.program; i++){
printf("进程P%d:", i);
for (int j = 0; j < banker.resource; j++){
scanf("%d", &banker.Allocation[i][j]);
//需求矩阵
banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];
//还剩的可利用资源
banker.Available[j] -= banker.Allocation[i][j];
}
}
return;
}
2.展示当前时刻的资源分配表和安全序列
(安全序列的Work是在安全性算法中定义的,只能在安全性算法中引用)
//展示当前资源分配表
void shownow(BANK banker){
printf("当前时刻资源分配表\n进程 Max Allocation Need Available\n");//5,8,8,8
int pause = 11 - banker.resource * 2;//空格,美观的的,没用
for (int i = 0; i < banker.program; i++){
printf("P%d ", i);//空格7个
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Max[i][j]);
for (int j = 0; j < pause;j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Allocation[i][j]);
for (int j = 0; j < (pause+7); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Need[i][j]);
if (i == 0){
for (int j = 0; j < (pause + 1); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Available[j]);
}
printf("\n");
}
}
//展示当前的安全序列
void showSafe(int *safe, int Work[], BANK banker){
printf("当前时刻安全序列\n进程 Work Need Allocation Work+Allocation");
int t = banker.program,k=0;
int pause = 12 - banker.resource * 2;//空格,美观的的,没用
for (int i = 0; i < banker.resource; i++)
Work[i] = banker.Available[i];
int temp;
while (t--){
temp = *(safe + k++);//进程号
printf("\nP%d ", temp);//空格7个
for (int j = 0; j < banker.resource; j++)
printf("%d ", Work[j]);
for (int j = 0; j < pause; j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", banker.Need[temp][j]);
for (int j = 0; j < pause; j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++){
printf("%d ", banker.Allocation[temp][j]);
Work[j] += banker.Allocation[temp][j];
}
for (int j = 0; j < (pause+6); j++)//对齐
printf(" ");
for (int j = 0; j < banker.resource; j++)
printf("%d ", Work[j]);
}
printf("\n");
return;
}
3.分配和取消分配
//分配
void GiveTo(BANK &banker,int pro[],int pro_id){
for (int i = 0; i < banker.resource; i++){
banker.Available[i] -= pro[i];
banker.Allocation[pro_id][i] += pro[i];
banker.Need[pro_id][i] -= pro[i];
}
return;
}
//取消分配
void GiveOut(BANK &banker, int pro[], int pro_id){
for (int i = 0; i < banker.resource; i++){
banker.Available[i] += pro[i];
banker.Allocation[pro_id][i] -= pro[i];
banker.Need[pro_id][i] += pro[i];
}
return;
}
4.两个比较函数,是否有运行完毕的进程
//比较a[]<=b[]是否都满足,多处应用到
bool compare(int a[], int b[]){
for (int i = 0; i < m; i++){
if (a[i]>b[i])return false;
}
return true;
}
//是否所有Finish[i]=true都满足
bool comp(bool a[]){
for (int i = 0; i < n; i++)
if (!a[i])return false;
return true;
}
//判断是否有进程达到最大需求,有就释放给它的资源,返回释放的进程号
int finishdoult(BANK &banker){
int fh = -1;
//判断是否有进程达到最大需求,fh记录进程号
for (int i = 0; i < banker.program; i++){
if (banker.Need[i][0] == 0){
int j;
for (j = 1; j < banker.resource; j++)
if (banker.Need[i][j])break;
if (j == banker.resource){
fh = i; break;
}
}
}
if (fh == -1)return fh;
for (int i = 0; i < banker.resource; i++){
banker.Need[fh][i] = banker.Max[fh][i];
banker.Allocation[fh][i] = 0;
banker.Available[i] += banker.Max[fh][i];
}
return fh;
}
5.安全性算法(银行家算法的步骤4)
只要有满足条件的执行即可,毕竟执行完可利用的资源只会变多
bool Savedoult(BANK banker,int *&safe){
//3.1设置两个向量
int Work[MAXSIZE],k=0;//k是保存安全序列的下标
for (int i = 0; i < banker.resource; i++)
Work[i] = banker.Available[i];
bool Finish[MAXSIZE] = { false };
//3.2:找一个满足条件的
for (int i = 0; i < banker.program; i++){
//找到,执行3.3
if (!Finish[i] && compare(banker.Need[i], Work)){
for (int j = 0; j < banker.resource; j++)
Work[j] += banker.Allocation[i][j];
Finish[i] = true;
*(safe+k++) = i;//存入安全序列
i = -1;//找到一个之后再从0开始循环(循环结束会++所以要设-1)
}
//没找到,执行3.4
else{
if (!comp(Finish))continue;
//如果都满足了即安全,展示安全序列并返回true
showSafe(safe, Work, banker);
return true;
}
}
//找不到安全序列则不安全
return false;
}
6.银行家算法
//银行家算法
void banksafe(BANK &banker,int *safe){
//步骤(0)请求(这里默认输入进程-1则退出)
int pro_id, pro[MAXSIZE];
printf("\n(-1则退出)进程:");
cin >> pro_id;
while (pro_id != -1){
if (pro_id < 0 || pro_id >= banker.program){
printf("超出进程数量限制\n进程:");
cin >> pro_id;
continue;
}
printf("进程P%d的请求变量:", pro_id);
for (int i = 0; i < banker.resource; i++)
scanf("%d", &pro[i]);
//步骤(1)
if (!compare(pro, banker.Need[pro_id])){
printf("超出它所宣布的最大值\n进程:");
cin >> pro_id;
continue;
}
//步骤(2)
if (!compare(pro, banker.Available)){
printf("尚无足够资源,需等待\n进程:");
cin >> pro_id;
continue;
}
//步骤(3)试探的分配
GiveTo(banker, pro, pro_id);
//步骤(4)安全性算法
if (Savedoult(banker, safe)){//若安全,正式分配,本次分配完成,输出安全序列和分配过后的资源分配表
printf("安全\n安全序列:");
for (int i = 0; i < banker.program; i++)
printf("%d ", *(safe + i));
printf("\n");
int fh = finishdoult(banker);//是否有运行完毕的进程
if (fh != -1){
printf("进程P%d已运行完成,释放出分配给它的资源\n",fh);
}
shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
printf("\n");
}
else{//若不安全,恢复原来的资源分配状态,等待该进程,执行其他的申请
printf("不安全\n");
GiveOut(banker, pro, pro_id);//取消分配
}
//步骤(0)请求
printf("\n进程:");
cin >> pro_id;
}
return;
}
7.主函数
int main(){
BANK banker;
init(banker);
//判断当前时刻是否安全
int *safe=(int*)malloc(n*sizeof(int));
if (Savedoult(banker, safe)){
printf("安全\n安全序列:");
for (int i = 0; i < banker.program; i++)
printf("%d ", *(safe + i));
int fh = finishdoult(banker);//是否有运行完毕的进程
if (fh != -1){
printf("进程P%d已运行完成,释放出分配给它的资源\n", fh);
}
shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
printf("\n");
}
else
printf("不安全\n");
banksafe(banker, safe);
system("PAUSE");
return 0;
}