天天看點

程序預防(銀行家算法)和檢測

在運作代碼前先添加六個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是其他值,就會運作銀行家算法,然後程式結束!!!

死鎖檢測就是從第一個程序開始檢查

繼續閱讀