C程序模擬實現銀行家算法


C程序模擬實現銀行家算法

 

  上周又做操作系統實驗,題目是用程序模擬實現銀行家算法,寫了半天還真有點暈,主要是因為想盡可能符合課本上的描述,所以寫出來的程序就比較惡心了,好了,銀行家算法就不多說了,不了解的可以先看一下百度百科上的描述,分段上代碼吧。完整代碼包下載地址:http://files.cnblogs.com/pianoid/Banker.rar

  首先要定義一些結構體,為了符合課本描述,我只定義了一個結構體:

  

typedef struct {
int A;
int B;
int C;
}RESOURCE;

  結構體里面的三個域分別表示三種資源的數量。

  根據課本例題上的數據初始化三個矩陣和一個向量。

復制代碼
//最大需求矩陣
RESOURCE Max[PROCESSES_NUMBER] =
{
{7,5,3},
{3,2,2},
{9,0,2},
{2,2,2},
{4,3,3}
};

//已分配資源數矩陣
RESOURCE Allocation[PROCESSES_NUMBER] =
{
{0,1,0},
{2,0,0},
{3,0,2},
{2,1,1},
{0,0,2}
};

//需求矩陣
RESOURCE Need[PROCESSES_NUMBER] =
{
{7,4,3},
{1,2,2},
{6,0,0},
{0,1,1},
{4,3,1}
};

//可用資源向量
RESOURCE Available = {3,3,2};
復制代碼

  為了能夠輸出安全狀態時的安全序列,還可以添加一個記錄安全序列的數組int SafeSequence[PROCESSED_NUMBER]。

  因為銀行家算法使用的是試探分配的策略,如果進程請求分配的資源既不大於自己尚需的資源,又不大於系統現存的資源,那就可以先試探着將資源分配給該進程,然后測試分配后是不是有可能造成死鎖,如果不會引起死鎖(即安全狀態)就可以完成分配,否則(即不安全狀態)就將試探分配的資源回收回來讓其等待。那么根據上面定義的數據就可以很容易的寫出試探分配和回收資源的函數。

復制代碼
//試探分配
void ProbeAlloc(int process,RESOURCE *res)
{
Available.A -= res->A;
Available.B -= res->B;
Available.C -= res->C;

Allocation[process].A += res->A;
Allocation[process].B += res->B;
Allocation[process].C += res->C;

Need[process].A -= res->A;
Need[process].B -= res->B;
Need[process].C -= res->C;
}

//若試探分配后進入不安全狀態,將分配回滾
void RollBack(int process,RESOURCE *res)
{
Available.A += res->A;
Available.B += res->B;
Available.C += res->C;

Allocation[process].A -= res->A;
Allocation[process].B -= res->B;
Allocation[process].C -= res->C;

Need[process].A += res->A;
Need[process].B += res->B;
Need[process].C += res->C;
}
復制代碼

  接下來就是安全性檢查函數了,在這個函數中還需要設置一個Work向量和一個Finish向量,函數實現主要就是通過一個for循環檢查試探分配后系統的可用資源數是否能滿足所有進程的需求,若能滿足某一個進程的需求,則假設分配其所需資源使之完成運行,然后就可以將資源回收以分配給其它進程,如果依照這種方法所有的進程都可以成功執行,那么現在的狀態就是安全狀態,否則即為不安全狀態,有可能引起死鎖。

復制代碼
bool SafeCheck()
{
RESOURCE Work = Available;
bool Finish[PROCESSES_NUMBER] = {false,false,false,false,false};
int i;
int j = 0;

for (i = 0; i < PROCESSES_NUMBER; i++)
{
//該進程是否已執行完畢
if(Finish[i] == false)
{
//是否有足夠的資源分配給該進程
if(Need[i].A <= Work.A && Need[i].B <= Work.B && Need[i].C <= Work.C)
{
//有則使其執行完成,並將已分配給該進程的資源全部回收
Work.A += Allocation[i].A;
Work.B += Allocation[i].B;
Work.C += Allocation[i].C;
Finish[i] = true;
safeSeq[j++] = i; //順便記錄下來安全序列
i = -1; //需要從開始重新進行遍歷
}
}
}

//如果所有進程的Finish向量都為true則處於安全狀態,否則為不安全狀態
for (i = 0; i < PROCESSES_NUMBER; i++)
{
if (Finish[i] == false)
{
return false;
}
}
return true;
}
復制代碼

有了以上三個函數就可以寫出請求分配資源的函數了。

復制代碼
//資源分配請求
bool request(int process,RESOURCE *res)
{
//request向量需小於Need矩陣中對應的向量
if(res->A <= Need[process].A && res->B <= Need[process].B && res->C <= Need[process].C)
{
//request向量需小於Available向量
if(res->A <= Available.A && res->B <= Available.B && res->C <= Available.C)
{
//試探分配
ProbeAlloc(process,res);

//如果安全檢查成立,則請求成功,否則將分配回滾並返回失敗
if(SafeCheck())
{
return true;
}
else
{
printf("安全性檢查失敗。原因:系統將進入不安全狀態,有可能引起死鎖。\n");
printf("正在回滾...\n");
RollBack(process,res);
}
}
else
{
printf("安全性檢查失敗。原因:請求向量大於可利用資源向量。\n");
}
}
else
{
printf("安全性檢查失敗。原因:請求向量大於需求向量。\n");
}
return false;
}
復制代碼

  好了,基本上所有必須的函數都已經寫完了,為了輸出更直觀的信息,也可以再加一個PrintTable函數將當前資源非配表顯示出來,我就不貼了,如果你想看的話請下載完整代碼吧。

  給出一個運行截圖。

銀行家算法

  上面啰嗦了一大堆,大概你也已經煩了,呵呵,代碼實在寫的丑,都不大好意思放了,不過有交流才有進步,如果有哪兒說不不正確,歡迎指正。

  完整代碼下載地址:http://files.cnblogs.com/pianoid/Banker.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM