题目描述
用程序实现银行家算法,为进程请求资源。
已分配资源数量 | 资源需求量 | |||||
---|---|---|---|---|---|---|
A | B | C | A | B | C | |
P1 | 2 | 1 | 2 | 3 | 4 | 7 |
P2 | 4 | 0 | 2 | 1 | 3 | 4 |
P3 | 3 | 0 | 5 | 0 | 0 | 3 |
P4 | 2 | 0 | 4 | 2 | 2 | 1 |
P5 | 3 | 1 | 4 | 1 | 1 | 0 |
请求序列如下:
a:进程P2请求资源(0,3,4)
b:进程P4请求资源(1,0,1)
c.进程P1请求资源(2,0,1)
d.进程P3请求资源(0,0,2)
程序功能及设计思路
程序功能:
用户输入一个进程请求资源,程序判断能否请求资源,如果分配不会导致死锁则分配资源,否者不能分配,输出告诉用户分配失败。
设计思路:
根据进程请求的资源进行判断,如果请求的资源比资源需求量还大,那么请求是不合理的,直接拒绝。否则预分配资源,预分配后进行安全判断是否会发生死锁(银行家算法),如果不会发生死锁那么就分配成功了,如果会发生死锁就分配失败,把预分配的资源回收。没有进程时结束执行。
程序功能及设计思路
数据结构:
int available[N] = { 2,3,3 };
int allocation[M][N] = { {2,1,2},{4,0,2},{3,0,5},{2,0,4},{3,1,4} };
int need[M][N] = { {3,4,7},{1,3,4},{0,0,3},{2,2,1},{1,1,0} };
int request[N] = { 0,0,0 };
由于资源总数、类型和进程的数量不多,就直接存在了数组中,available为当前系统可用的各种资源量,allocation为各进程当前已分配到的各类资源,need为各进程对资源的剩余需求量,request为当前某进程请求的每种资源量。
算法设计:
//比较两个数组的大小,如果a数组1的每一个元素都大于数组2的对应元素就返回false,否则返回true
bool previousIsBig(int* arr1, int* arr2)
{
for (int i = 0;i < N;i++)
{
if (arr1[i] < arr2[i])
{//有一个不符合就返回false
return false;
}
}
//否则返回true
return true;
}
算法分析:两个数组逐个元素进行比较,只有arr1数组的所有元素大于arr2数组对应位置的所有元素才返回ture,有一个不符合要求就返回false。
//安全状态判别算法
bool safeText()
{
int i, j;
bool flag=true;
//每个进程运行的状态,初始都为false
bool finish[M];
for (i = 0;i < M;i++)
{
finish[i] = false;
}
//将现有资源转移到work中
int work[N];
for (i=0;i < N;i++)
{
work[i] = available[i];
}
//一直循环查找未完成但是现在能够完成的进程
while (flag)
{
flag = false;
for (i = 0;i < M;i++)
{
if (finish[i] == false && previousIsBig(work, need[i]))
{//标记为完成且释放掉占用的资源
finish[i] = true;
for (j = 0;j < N;j++)
{//释放资源
work[j] += need[i][j];
}
flag = true;
}
}
}
//如果处理完后有一个进程未完成,说明是不安全的
for (i = 0;i < M;i++)
{
if (finish[i] == false) return false;
}
//否则就是安全的
return true;
}
算法思想:这个算法用于判断是否安全,finish数组用于存储进程的运行状态,初始状态都为未完成false。一直循环查找未完成但是现在能够完成的进程,将这个进程完成并且运行状态标记为true,完成后释放掉所有申请的资源,再继续寻早下一个能完成的资源,直到没有资源可完成。循环结束后对finish的所有元素进行判断,如果为都为true说明所有进程都可以完成,系统是安全的,否则就是有进程无法完成,即系统进入了死锁。
//试探性分配
void distribution(int pi, int* request)
{
int i = 0;
for (i;i < N;i++)
{
available[i] -= request[i];
allocation[pi][i] += request[i];
need[pi][i] -= request[i];
}
}
算法思想:试探性分配,根据请求的资源,系统可用的各种资源量减少相应的资源数,该进程当前已分配到的各类资源增加,该进程对资源的剩余需求量减少。
//分配失败,取消试探性分配
void cancle(int pi, int* request)
{
int i = 0;
for (i;i < N;i++)
{
available[i] += request[i];
allocation[pi][i] -= request[i];
need[pi][i] += request[i];
}
}
算法思想:将分配的资源全部回收。
//银行家算法,第一个参数为进程编号,第二个为这个进程各项资源需要的数量
void bank(int pi, int* request)
{
//先判断需求是否合理
if (previousIsBig(request, need[pi]))
{
//cout << "error" << endl;
cout << "请求资源数不合理,请求失败!" << endl;
return;
}
//先判断系统是否有足够的盈余资源
if (!previousIsBig(available, request))
{
cout << "系统没有这么多资源,请求失败!" << endl;
return;
}
//试探性分配
distribution(pi, request);
//判断是否安全,如果合法就分配
if (safeText)
{
cout << "分配资源成功!" << endl;
return;
}
else
{//不合法撤回分配
cancle(pi, request);;
cout << "分配资源会导致死锁,分配失败!" << endl;
return;
}
}
算法思想:先判断请求资源是否合理,即请求的资源数要小于等于资源需求量,再判断系统是否有足够的盈余资源。如果都满足,就先试探性分配,试探性分配后检查系统是否还处于安全状态,如果为安全状态则分配成功,否则分配该资源将导致死锁,拒绝分配并将之前试探性分配的资源回收到系统中。
源代码
stdfax.h
#ifndef STDAFX_H_INCLUDE
#define STDAFX_H_INCLUDE
#include <iostream>
#define M 5 //进程数量
#define N 3 //资源种类
using namespace std;
#endif // !STDAFX_H_INCLUDE
bank.h
#ifndef BANK_H_INCLUDE
#define BANK_H_INCLUDE
#include "stdafx.h"
int available[N] = { 2,3,3 }; //当前系统可用的各种资源量
int allocation[M][N] = { {2,1,2},{4,0,2},{3,0,5},{2,0,4},{3,1,4} }; //各进程当前已分配到的各类资源
int need[M][N] = { {3,4,7},{1,3,4},{0,0,3},{2,2,1},{1,1,0} }; //各进程对资源的剩余需求量
int request[N] = { 0,0,0 }; //当前某进程请求的每种资源量,默认都为0
//比较两个数组的大小,如果a数组1的每一个元素都大于数组2的对应元素就返回false,否则返回true
bool previousIsBig(int* arr1, int* arr2)
{
for (int i = 0;i < N;i++)
{
if (arr1[i] < arr2[i])
{//有一个不符合就返回false
return false;
}
}
//否则返回true
return true;
}
//只有三个元素的数组相加
int* addArr(int* arr1, int* arr2)
{
int result[3];
for (int i = 0;i < 3;i++)
{
result[i] = arr1[i] + arr2[i];
}
return result;
}
//安全状态判别算法
bool safeText()
{
int i, j;
bool flag=true;
//每个进程运行的状态,初始都为false
bool finish[M];
for (i = 0;i < M;i++)
{
finish[i] = false;
}
//将现有资源转移到work中
int work[N];
for (i=0;i < N;i++)
{
work[i] = available[i];
}
//一直循环查找未完成但是现在能够完成的进程
while (flag)
{
flag = false;
for (i = 0;i < M;i++)
{
if (finish[i] == false && previousIsBig(work, need[i]))
{//标记为完成且释放掉占用的资源
finish[i] = true;
for (j = 0;j < N;j++)
{//释放资源
work[j] += need[i][j];
}
flag = true;
}
}
}
//如果处理完后有一个进程未完成,说明是不安全的
for (i = 0;i < M;i++)
{
if (finish[i] == false) return false;
}
//否则就是安全的
return true;
}
//试探性分配
void distribution(int pi, int* request)
{
int i = 0;
for (i;i < N;i++)
{
available[i] -= request[i];
allocation[pi][i] += request[i];
need[pi][i] -= request[i];
}
}
//分配失败,取消试探性分配
void cancle(int pi, int* request)
{
int i = 0;
for (i;i < N;i++)
{
available[i] += request[i];
allocation[pi][i] -= request[i];
need[pi][i] += request[i];
}
}
//银行家算法,第一个参数为进程编号,第二个为这个进程各项资源需要的数量
void bank(int pi, int* request)
{
//先判断需求是否合理
if (previousIsBig(request, need[pi]))
{
cout << "请求资源数不合理,请求失败!" << endl;
return;
}
//先判断系统是否有足够的盈余资源
if (!previousIsBig(available, request))
{
cout << "系统没有这么多资源,请求失败!" << endl;
return;
}
//试探性分配
distribution(pi, request);
//判断是否安全,如果合法就分配
if (safeText)
{
cout << "分配资源成功!" << endl;
return;
}
else
{//不合法撤回分配
cancle(pi, request);;
cout << "分配资源会导致死锁,分配失败!" << endl;
return;
}
}
#endif // !BANK_H_INCLUDE
main.cpp
#include "bank.h"
int main()
{
//p2请求资源(0,3,4)
int re[3] = { 0, 3,4 };
cout << "p2请求资源:";
bank(1, re);
//p4请求资源(1,0,1)
re[0] = 1, re[1] = 0, re[2] = 1;
cout << "p4请求资源:";
bank(3, re);
//p1请求资源(2,0,1)
re[0] = 2, re[1] = 0, re[2] = 1;
cout << "p1请求资源:";
bank(0, re);
//p3请求资源(0,0,2)
re[0] = 0, re[1] = 0, re[2] = 2;
cout << "p3请求资源:";
bank(2, re);
return 0;
}