1. 问题描述
1.1 银行家算法
申请者事先说明对各类资源的最大需求量。在进程活动期间动态申请某类资源时,由系统审查系统现有该类资源的数目是否能满足当前进程的最大需求量,如能满足就予以分配,否则拒绝。
1.2 伪代码
#define n 5 //进程个数
#define m 3 //资源种类
int Available[m],Alloc[n][m],Need[n][m];
main() {
int request[m];
input( );
while (1) {
read_req( );
if (请求结束) break;
(1) if (!(requesti <= Needi)) 表示非法请求;
(2) if (!(requesti <= Available)) 则Pi阻塞;
(3)试探性分配
Available=Available - Requesti;
Alloci=Alloci + Requesti;
Needi=Needi - Requesti;
(4)若新状态安全,则实际分配资源给Pi,否则取消试探性分配。
}
}
1.3 安全状态判别算法
(1)设置Finish=(false,…,false) , work=Available
(2)循环查找满足下列条件的进程pi , 最多循环n次 : Finish[i]=false且Needi<=work
(3)若找到则Finish[i]=true;work=work+Alloci; 转(2)
(4)若Finish=(true,…,true) 则安全,否则不安全。
1.4 测试数据
3种类型的资源m=3
进程个数n=5
Available=(2,3,3);
请求序列如下:
a) 进程P2请求资源(0,3,4)
b) 进程P4请求资源(1,0,1)
c) 进程P1请求资源(2,0,1)
d) 进程P3请求资源(0,0,2)
2.实现思路
2.1 文件读取
首先将当前请求的资源、最大资源需求和已分配的资源写入文件,程序会读取这些文件并处理资源请求。其中每个文件的每行第一个数代表线程,每行剩下的值代表每个资源的大小。
2.2 试探性分配
对于每个请求序列,首先试探性分配,判断该资源请求序列是否可以被满足。若满足则可以将资源进行分配,否则不能分配。
用户可以输入一个想要获得的序列个数,则程序会输出所有能够分配的请求序列。该过程如下:首先产生一个排列permutation,代表当前的资源请求顺序。分别设计判断当前请求是否合法isLegal(int numOfReq)和是否可以满足notBlocked(int numOfReq)的两个函数。其中的参数numOfReq代表线程。对于其中一个返回值为false的序列,不能将资源进行分配,因此终止程序,尝试下一个请求序列,重新进行试探性分配。
3. 核心代码
int detectiveAlloc(int permutation[]) {
order.clear();
AllocOrder.clear();
for (int i = 0; i < RESOURCE; ++i) {
Work[i] = Available[i];
}
for (int i = 0; i < PROCESS; ++i) {
for (int j = 0; j < RESOURCE; ++j) {
Alloc_[i][j] = Alloc[i][j];
Need_[i][j] = Need[i][j];
}
}
for (int i = 0; i < PROCESS; ++i) {
// 请求是否合法
if (!isLegal(permutation[i])) {
printf("\n %d is illegal \n", permutation[i]);
exit(0);
}
// 是否可分配给该进程
if (!notBlocked(permutation[i])) {
//if (i == 0);
break;
}
order.push_back(permutation[i]);
for (int j = 0; j < RESOURCE; ++j) {
// Work减少
Work[j] -= Request[permutation[i]][j];
// Need减少
Need_[permutation[i]][j] -= Request[permutation[i]][j];
// Alloc增加
Alloc_[permutation[i]][j] += Request[permutation[i]][j];
}
for (int k = 0; k < PROCESS; ++k) {
bool flag = true;
for (int j = 0; j < RESOURCE; ++j) {
// 资源是否释放
if (Need_[k][j] > Work[j]) {
flag = false;
break;
}
}
if (flag == true && std::count(AllocOrder.begin(), AllocOrder.end(), k) == 0) {
AllocOrder.push_back(k);
for (int j = 0; j < RESOURCE; ++j) {
Work[j] += Alloc_[k][j];
}
break;
}
}
}
return AllocOrder.size() == PROCESS ? 1 : 0;
}
4.运行结果
读取文件并输入请求序列个数:
输出满足条件的请求序列以及给该序列分配资源的顺序: