数据定义:
- E:Existing Resource 表示当前资源总量
- A:Available Resource 表示当前可分配资源
- MaxR:表示每种资源需要的最大需求量
- C:Current Resource 表示当前已分配的资源
- R:每种资源的最大可能请求
- N:当前进程申请的资源
数据间的关系:
$$R = maxR – C$$
$$\sum{C}+ A = E$$
采用的数据结构:
假设资源种类有RNum种,进程数量共有PNum个
则E、A、N均为大小为RNum的向量,含义为:
E[i]:表示第i种资源的资源总量
A[i]:表示第i种资源的当前剩余资源,即为当前可分配资源
N[i]:表示当前提出申请的进程,对第i种资源的申请量
因此,以上三种数据的数据结构均用一维数组表示即可
maxR、C、R为二维矩阵,矩阵的行表示进程的各种资源量,矩阵的列代表不同进程,如下表:
maxR | C | R | |
---|---|---|---|
P1 | (70,40,60) | (20,20,20) | (50,20,40) |
P2 | (40,40,50) | (10,10,10) | (30,30,40) |
P3 | (50,30,60) | (30,30,30) | (20,0,30) |
各数据的定义如下:
int E[MAX_RNUM],A[MAX_RNUM],PNum,RNum;
int maxR[MAX_PNUM][MAX_RNUM],
C[MAX_PNUM][MAX_RNUM],
R[MAX_PNUM][MAX_RNUM];
设计思路:
要在进程分配时避免死锁,采用如下实现思路:
在每次进程分配资源之前,对当前系统进行死锁检测,判断系统是否有可能产生死锁,若可能,则拒绝此次资源分配。
要进行死锁检测,采用银行家算法:
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
根据上述的数据结构,进行如下操作:
设进程Pi提出请求N[i],则银行家算法按如下规则进行判断。
(1)如果N[i] [j]<= Ri,则转(2);否则,出错。
(2)如果N[i] [j]<= A[j],则转(3);否则,等待。
(3)系统试探分配资源,修改相关数据:
A[j]-=Ni;
Ci+=Ni;
Ri-=Ni;
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
我们采用一个标记数组finished[PNum]来标记进程P[i]是否通过上述试探性分配
如果所有进程全部都通过试探性分配,即所有进程都被标记,说明系统安全,并可根据资源分配的顺序,输出此时系统的安全性序列Order。否则,未被标记的进程(即Finished[i] = false)是可能产生死锁的进程。
因此,只有所有进程都被标记,FinishedNum == PNum时,死锁检测算法才能返回true,否则返回false。
int Safe(FILE * fp){
int FinishedNum = 0,i,Finished[MAX_PNUM] = {0};
int testA[MAX_RNUM];
for(int i = 1;i <= RNum;i++){
testA[i] = A[i];
}
int Order[MAX_PNUM] = {0},k = 0;
while(FinishedNum != PNum){
for(i = 1;i <= PNum;i++){
if(Finished[i] == 0 && find(R[i], testA)){
for(int j = 1;j <= RNum;j++){
testA[j] += C[i][j];
}
Finished[i] = 1;
Order[k++] = i;//记录
FinishedNum++;
if(FinishedNum == PNum){
//输出Order到文件
fprintf(fp,"Process Safe Order:");
for(i = 0;i < PNum;i++){
fprintf(fp,"%d ",Order[i]);
}
fprintf(fp,"\n");
break;
}
break;
}
}
if(i > PNum){
return -1;
}
}
return 1;
}
若死锁检测为真,则根据当前进程P[i]提出的资源申请N[RNum]进行资源分配,更新数据结构。
代码如下:
void ProcessAsk(int k,int *N,FILE * fp){//进程P_k想要申请N个资源
if(Safe(fp) == 1){
printf("SYSTEM SAFE! Resource Allocating...\n");
if(in_Scale(A,N) && in_Scale(R[k],N)){//A-N>=0 && R[k] - N >= 0
for(int j = 1;j <= RNum;j++){
C[k][j] += N[j];
}
for(int j = 1;j <= RNum;j++){
R[k][j] -= N[j];
}
if(isZero(R[k])){
for(int j = 1;j <= RNum;j++){
A[j] += maxR[k][j];
}
printf("Process%d have released Resource!\n",k);
}
for(int j = 1;j <= RNum;j++){
A[j] -= N[j];
}
fprintf(fp,"Allocate P%d SUCCESS!\n",k);
printf("Allocate P%d SUCCESS!\n",k);
showInfo();
// write2File(fp);
}else{
printf("FAILED!Resource OverScale!\n");
}
}else{
printf("SYSTEM WARNING! ");
showInfo();
fprintf(fp,"Allocate P%d FAILED!\n",k);
}
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#define MAX_PNUM 501
#define MAX_RNUM 100
int E[MAX_RNUM],A[MAX_RNUM],PNum,RNum;
int maxR[MAX_PNUM][MAX_RNUM],C[MAX_PNUM][MAX_RNUM],R[MAX_PNUM][MAX_RNUM];
void Init(){
int i;
printf("Input the Resource Num:");
scanf("%d",&RNum);
printf("Input the Existing Resource:");
for(int i = 1;i <= RNum;i++){
scanf("%d",&E[i]);
}
for(int i = 1;i <= RNum;i++){
A[i] = E[i];
}
printf("Input the Num of Process:");
scanf("%d",&PNum);
printf("Input the MAX_Need Resource of every Process:");
for(i = 1;i <= PNum;i++){
for(int j = 1;j <= RNum;j++){
scanf("%d",&maxR[i][j]);
C[i][j] = 0;
R[i][j] = maxR[i][j];
}
}
}
int find(int * Ri,int * A){
for(int i = 1;i <= RNum;i++){
if(Ri[i] > A[i]) return 0;
}
return 1;
}
int Safe(FILE * fp){
int FinishedNum = 0,i,Finished[MAX_PNUM] = {0};
int testA[MAX_RNUM];
for(int i = 1;i <= RNum;i++){
testA[i] = A[i];
}
int Order[MAX_PNUM] = {0},k = 0;
while(FinishedNum != PNum){
for(i = 1;i <= PNum;i++){
if(Finished[i] == 0 && find(R[i], testA)){
for(int j = 1;j <= RNum;j++){
testA[j] += C[i][j];
}
Finished[i] = 1;
Order[k++] = i;//记录
FinishedNum++;
if(FinishedNum == PNum){
//输出Order到文件
fprintf(fp,"Process Safe Order:");
for(i = 0;i < PNum;i++){
fprintf(fp,"%d ",Order[i]);
}
fprintf(fp,"\n");
break;
}
break;
}
}
if(i > PNum){
return -1;
}
}
return 1;
}
void printVector(int * vector,int n){
printf("(");
for(int i = 1;i <= n;i++){
printf("%d ",vector[i]);
}
printf(")");
}
void showInfo(){
int i;
printf("*********************************************\n");
printf("Existing Resource:");
printVector(E, RNum);
printf(",Available Resource:");
printVector(A, RNum);
printf("\n");
printf("maxR:\n");
for(int i = 1;i <= PNum;i++){
for(int j = 1;j <= RNum;j++){
printf("%d ",maxR[i][j]);
}
printf("\n");
}
printf("CurrentR\n");
for(int i = 1;i <= PNum;i++){
for(int j = 1;j <= RNum;j++){
printf("%d ",C[i][j]);
}
printf("\n");
}
printf("Request:\n");
for(int i = 1;i <= PNum;i++){
for(int j = 1;j <= RNum;j++){
printf("%d ",R[i][j]);
}
printf("\n");
}
printf("*********************************************\n");
}
//void write2File(FILE * fp){
// int i;
// fprintf(fp, "*********************************************\n");
// fprintf(fp, "Existing Resource:%d, Available Resource:%d\n",E,A);
// fprintf(fp,"maxR\tCurrentR\tRequest\n");
// for(i = 1;i <= PNum;i++){
// fprintf(fp,"%d\t\t%d\t\t\t%d\n",maxR[i],C[i],R[i]);
// }
// fprintf(fp,"*********************************************\n");
//
//}
int in_Scale(int * vector,int * N){
for(int j = 1;j <= RNum;j++){
if(vector[j] < N[j]) return 0;
}
return 1;
}
int isZero(int *Rk){
for(int j = 1;j <= RNum;j++){
if(Rk[j] != 0) return 0;
}
return 1;
}
void ProcessAsk(int k,int *N,FILE * fp){//进程P_k想要申请N个资源
if(Safe(fp) == 1){
printf("SYSTEM SAFE! Resource Allocating...\n");
if(in_Scale(A,N) && in_Scale(R[k],N)){//A-N>=0 && R[k] - N >= 0
for(int j = 1;j <= RNum;j++){
C[k][j] += N[j];
}
for(int j = 1;j <= RNum;j++){
R[k][j] -= N[j];
}
if(isZero(R[k])){
for(int j = 1;j <= RNum;j++){
A[j] += maxR[k][j];
}
printf("Process%d have released Resource!\n",k);
}
for(int j = 1;j <= RNum;j++){
A[j] -= N[j];
}
fprintf(fp,"Allocate P%d SUCCESS!\n",k);
printf("Allocate P%d SUCCESS!\n",k);
showInfo();
// write2File(fp);
}else{
printf("FAILED!Resource OverScale!\n");
}
}else{
printf("SYSTEM WARNING! ");
showInfo();
fprintf(fp,"Allocate P%d FAILED!\n",k);
}
}
int main(int argc, char *argv[]) {
Init();
FILE * fp;
int i;
if((fp=fopen("test.txt", "w+")) == NULL){
fprintf(stdout, "Can't open \"test\" file.\n ");
exit(EXIT_FAILURE);
}
showInfo();
// write2File(fp);
while(1){
int k,N[RNum];
printf("\nInput the ProcessNum and the Ask for Resource:");
scanf("%d",&k);
printf("Input the ask for Resource:");
for(int i = 1;i <= RNum;i++){
scanf("%d",&N[i]);
}
if(k <= 0 || k > PNum){
printf("Process NOT exist!\n");
break;
}else{
// fprintf(fp, "\nProcess%d asking for %d Resource\n",k,N);
}
ProcessAsk(k, N, fp);
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。