在运行代码前先添加六个txt文件,分别是:mount,maxRequest,allocation,need,available,request。
mount:依次存放进程数和资源种类数;
maxRequest:存放一个矩阵,进程最资源的最大需求矩阵;
allocation:存放一个矩阵,进程已获得的各类资源的数量的矩阵;
need:存放一个矩阵,进程仍然需要各类资源数量的矩阵;
available:当前系统拥有的各类资源的向量;(可以理解成一维,长度是资源种类数)
request:存放某个进程对各类资源的申请;(可以理解成一维,长度是资源种类数)
然后是代码:我用C语言写的,在codeblocks上可以运行,在其他的软件上面应该也是可以的。
/* 将各个矩阵以全局变量的形式存储 死锁检测。死锁预防。 */ #include <stdio.h> #define MAXINT 999 //进程对于资源的最大需求矩阵 int maxRequest[10][10]={0}; //每个进程已获得的每类资源的矩阵 int allocation[10][10]={0}; //每个进程仍然需要的每类资源的 矩阵 int need[10][10]={0}; //表示系统各类可用资源数目 int available[10]={0}; //表示这个进程请求各类资源的数目 int request[10]={0}; //这个数组应该是用来保存 进程 安全执行的顺序 int safeSeries[10]={0}; //分别是进程数量和资源种类量 int processNum=0; int resourceNum=0; //临时存储资源available[] int work1[10]={0}; int Safe[10]={0}; int Init() { FILE *fp1,*fp2,*fp3,*fp4,*fp5,*fp6; int i = 0,j = 0; fp1=fopen("D:\\mount.txt","r+"); fp2=fopen("D:\\maxRequest.txt","r+"); fp3=fopen("D:\\allocation.txt","r+"); fp4=fopen("D:\\need.txt","r+"); fp5=fopen("D:\\available.txt","r+"); if(fp1==NULL) printf("打开文件失败!\n"); else { printf("接收进程数目,资源数目中···\n"); fscanf(fp1,"%d %d ",&processNum,&resourceNum); /0 printf("%d %d\n",processNum,resourceNum); } if(fp2==NULL) printf("打开文件失败!\n"); else { printf("接收进程所需最大资源矩阵中···\n"); for(i= 0;i< processNum;i++) for(j= 0;j<resourceNum;j++) fscanf(fp2,"%d ",&maxRequest[i][j]); / for(i= 0;i<processNum;i++) {for(j= 0;j<resourceNum;j++) printf("%d ",maxRequest[i][j]); printf("\n"); } } if(fp3==NULL) printf("打开文件失败!\n"); else { printf("接收分配矩阵中···\n"); for(i= 0;i<processNum;i++) for(j= 0;j<resourceNum;j++) fscanf(fp3,"%d",&allocation[i][j]); / for(i= 0;i<processNum;i++) {for(j= 0;j<resourceNum;j++) printf("%d ",allocation[i][j]); printf("\n"); } } if(fp4==NULL) printf("打开文件失败!\n"); else { printf("接收当前需求矩阵···\n"); for(i= 0;i<processNum;i++) for(j= 0;j<resourceNum;j++) fscanf(fp4,"%d",&need[i][j]); for(i= 0;i<processNum;i++) {for(j= 0;j<resourceNum;j++) printf("%d ",need[i][j]); printf("\n"); } } if(fp2==NULL) printf("打开文件失败!\n"); else { printf("接收当前资源可用数目···\n"); for(i= 0;i<resourceNum;i++) fscanf(fp5,"%d",&available[i]); } return 0; } //这个函数就是将 刚刚输入的信息输出来 int showInfo() { int i,j; printf("当前资源剩余量:\n"); for(i= 0;i< resourceNum;i++) printf("%d ",available[i]); printf("\n"); printf(" PID\t MAX\t Allocation\t Need\n"); for(i= 0;i<processNum;i++) { //i是某个值,表示编号为i的进程的对各个资源的 最大需求,已分配,仍然需求 量; printf(" P%d\t",i); for(j= 0;j<resourceNum;j++) printf("%d ",maxRequest[i][j]); printf("\t\t"); for(j= 0;j<resourceNum;j++) printf("%d ",allocation[i][j]); printf("\t\t"); for(j= 0;j<resourceNum;j++) printf("%d ",need[i][j]); printf("\t\t"); printf("\n"); } printf("\n\n"); return 0; } /*没有问题*/ int safe() { int found=0,i=0,j=0; int key1=0,key2=0,k=0,m=0; //存放系统资源信息的临时数组 int work[10]={0}; int finished[10]={0}; for(i=0;i<resourceNum;i++) { work[i]=available[i]; //printf("%d ",work[i]); } while(1) { found=0; for(i=0;i<processNum;i++) { if(finished[i]==0) { for(j=0;j<resourceNum;j++) { if(need[i][j]<=work[j]) { continue; } else {//不满足,需要等待 break; } } if(j==resourceNum) { for(m=0;m<resourceNum;m++) work[m]=work[m]+allocation[i][m]; finished[i]=1; safeSeries[k]=i; k++; found=1; } } } if(found==0) break; } for(i=0;i<processNum;i++) { if(finished[i]==0) { printf("死锁!\n"); break; } } if(i==processNum) { printf("系统安全!\n"); printf("安全序列:"); for(i=0;i<processNum;i++) { printf("P%d ",safeSeries[i]); } } return 0; } //pro是申请资源的进程 int banker(int pro) { int key1=0,key2=0; int i=0,j=0; int finished[10]={0}; //当前资源可用的总量向量 for(i=0;i<resourceNum;i++) work1[i]=available[i]; for(i=0;i<resourceNum;i++) { finished[i]=0; //通过输出请求向量 ,可以知道请求美玉问题 printf("%d ",request[i]); } for(j=0;j<resourceNum;j++) { if(request[j]<=need[pro][j]) continue; else { printf("申请失败!\n"); return 0; } } for(j=0;j<resourceNum;j++) { if(request[j]<=work1[j]) continue; else { //进程等待 printf("目前没有足够的资源!\n请重新输入···"); return 0; } } //如果申请成功,就试探分配 if(j==resourceNum) { for(i=0;i<resourceNum;i++) { work1[i]=work1[i]-request[i]; allocation[pro][i]=allocation[pro][i]+request[i]; need[pro][i]=need[pro][i]-request[i]; //finished[pro]=1; //Safe[pro]=1; } showInfo(); for(i=0;i<resourceNum;i++) printf("%d ",work1[i]); printf("\n"); } //试探分配之后进行安全检查,安全就这么分配(即有安全序列)。 if(issafe(pro)) printf("申请分配成功!\n"); else { printf("申请失败!申请后会产生死锁!\n"); for(i=0;i<resourceNum;i++) { work1[i]=work1[i]+request[i]; need[pro][i]=need[pro][i]+request[i]; allocation[pro][i]=allocation[pro][i]-request[i]; } } return 0; } //在试探分配的基础上进行 看一看有没有一个安全序列 int issafe(int pro) { int finished[10]={0}; int work2[10]={0}; int i=0,j=0,m=0; int k=0,found=0; //finished[pro]=1; for(i=0;i<resourceNum;i++) work2[i]=work1[i]; for(i=0;i<processNum;i++) finished[i]=0; while(1) { found=0; for(i=0;i<processNum;i++) { if(finished[i]==0) { for(j=0;j<resourceNum;j++) { if(need[i][j]<=work1[j]) { continue; } else {//不满足,需要等待 break; } } if(j==resourceNum) { for(m=0;m<resourceNum;m++) { work1[m]=work1[m]+allocation[i][m]; } finished[i]=1; Safe[k]=i; k++; found=1; printf("!!@"); } } } if(found==0) break; } for(i=0;i<processNum;i++) printf("%d ",finished[i]); printf("\n"); for(i=0;i<processNum;i++) { if(finished[i]==0) { printf("sdf"); return 0; } } if(i==processNum){ return 1; } } int main() { int i=0,pro=-1; int choice=0; FILE *fp6=NULL; //初始化 Init(); //显示刚刚输入的信息 showInfo(); printf("请选择:"); scanf("%d",&choice); //死锁检查 if(choice==1) safe(); else { printf("请输入申请资源的进程:"); scanf("%d",&pro); printf("导入进程所申请资源信息中:A= B= C= ···\n"); //request是全局变量 //这里不要忘记加上&取地址符 fp6=fopen("D:\\request.txt","r+"); for(i=0;i<resourceNum;i++) fscanf(fp6,"%d",&request[i]); banker(pro); } return 0; }
运行结果:
输入1,会检测当前是否安全,安全的话会输入安全序列。
输入其他值:
再输入申请资源的进程号 就会出现这样。(没有简化输出看着有点乱,主要看:输出的 申请分配成功!)
准备工作:上面介绍了要在D盘放六个文件,看了代码就知道为什么了。在六个文件中要事先输入 信息,可以找一个例题(我会给一个)。这样我在运行的时候就不需要一遍一遍的向控制台输入 信息了。给出我的例子
代码分为两个大的内容,一个是死锁预防;一个是死锁检测(safe函数);
在主函数中 让输入 choice,如果choice是1那么就进行死锁检测,就是检测当前时刻有没有安全序列,有安全序列的话系统就是安全的。程序结束!!!
如果choice是其他值,就会运行银行家算法,然后程序结束!!!
死锁检测就是从第一个进程开始检查