数据定义:

  • 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为二维矩阵,矩阵的行表示进程的各种资源量,矩阵的列代表不同进程,如下表:

maxRCR
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;
}

crab
1 声望0 粉丝