操作系统课程设计--银行家算法的模拟实现
發(fā)一些大三操作系統(tǒng)的實(shí)驗(yàn)代碼吸引閱讀量吧,當(dāng)時(shí)做實(shí)驗(yàn)的時(shí)候看見網(wǎng)上很多人寫的代碼并不好,而且很多人都有錯(cuò)誤的地方。如果好的話希望能點(diǎn)贊關(guān)注。
本篇文章選自課程設(shè)計(jì)報(bào)告的部分,所以相比前兩篇實(shí)驗(yàn)詳細(xì)很多,我盡量貼一些重要的部分出來
在多道程序系統(tǒng)中,多個(gè)進(jìn)程在運(yùn)行中對(duì)于資源的爭(zhēng)奪而造成了一種僵局—死鎖,若無外力作用,則這些進(jìn)程均無法向前推進(jìn)。如此,尋求避免死鎖的方法就顯得尤為重要。死鎖產(chǎn)生的原因一般有三種:競(jìng)爭(zhēng)不可搶占性資源、競(jìng)爭(zhēng)可消耗性資源、進(jìn)程的推進(jìn)順序不當(dāng)。因此,在當(dāng)前有限資源下,找到一組合法的順序(稱之為安全序列)執(zhí)行,便能有效的避免死鎖的產(chǎn)生。銀行家算法便是最有代表性的避免死鎖的算法,它是由艾茲格·迪杰斯特拉在1965年為T.H.E系統(tǒng)設(shè)計(jì)的一種避免死鎖產(chǎn)生的算法。本次課程設(shè)計(jì)通過設(shè)計(jì)并編寫程序來模擬銀行家算法的執(zhí)行過程。
一、數(shù)據(jù)結(jié)構(gòu)的選擇
a.將每個(gè)進(jìn)程都視作一個(gè)對(duì)象,因此使用類進(jìn)行存儲(chǔ)和讀取,并重載運(yùn)算符用于數(shù)據(jù)的拷貝。為了實(shí)現(xiàn)資源數(shù)的可變性,則使用STL(Standard Template Library標(biāo)準(zhǔn)模板庫,C++的一部分)中的vector容器存儲(chǔ)各資源已用的資源和需要的資源數(shù)(int型)。類的定義如下所示:
class Process//使用一個(gè)類的對(duì)象表示一個(gè)進(jìn)程{public:stringID;//進(jìn)程名vector<int>UsedResource;//已用各資源數(shù)vector<int>NeedResource;//對(duì)應(yīng)的所需資源數(shù)Process&operator=(constProcess &p) //運(yùn)算符重載用于賦值{if(this != &p){this->ID= p.ID;this->UsedResource= p.UsedResource;this->NeedResource= p.NeedResource;}return*this;}};b.為了對(duì)進(jìn)程數(shù)和資源數(shù)進(jìn)行存儲(chǔ),分別定義了int型變量ProcessCount、ResourceCount用于存儲(chǔ)進(jìn)程數(shù)和資源數(shù)。
c.為了對(duì)各資源的可用資源數(shù)進(jìn)行存儲(chǔ)和讀取,定義了vector<int>Available用于存儲(chǔ)可用資源數(shù)。
d.為了存儲(chǔ)各進(jìn)程的信息,使用對(duì)象的list,即STL中的鏈表list<Process> n。
e.因?yàn)樵诎踩运惴ㄟ\(yùn)算時(shí)需要更改進(jìn)程中的資源信息和當(dāng)前可用資源信息,所以分別定義了list<Process> Copy、list<Process> Copy_2、vector<int>calc在運(yùn)算前對(duì)當(dāng)前進(jìn)程的鏈表和當(dāng)前資源信息進(jìn)行拷貝,并用以運(yùn)算。
f.因?yàn)閷?duì)進(jìn)程的初始化較為繁瑣,所以定義了list<int>UsedResourceBuffer、list<int>NeedResourceBuffer用于對(duì)Process的初始化。
g.定義了list<string>Safeyqueue用于存儲(chǔ)安全序列。
二、模塊的劃分
由于算法規(guī)模較小,所以大多數(shù)的實(shí)現(xiàn)均將其寫在main函數(shù)中的while循環(huán)體中,需要使用的變量等也盡量定義為全局變量。但在選擇后分別完成了不同的且重要的功能。除main函數(shù)中的部分,其它單獨(dú)出的模塊的功能如下:
a.SetProcess:對(duì)單個(gè)進(jìn)程的信息進(jìn)行初始化,返回初始化完成的進(jìn)程對(duì)象。
b.ShowAllProcess:對(duì)所有進(jìn)程進(jìn)行顯示
c.safetyCheak:用于安全性算法,并對(duì)安全序列進(jìn)行初始化
d.ShowQueue:顯示安全序列的情況。
三、實(shí)現(xiàn)代碼如下
#include <iostream> #include <iomanip> #include <string> #include <vector> #include <list> #include <cstdlib> using namespace std; class Process//使用一個(gè)類的對(duì)象表示一個(gè)進(jìn)程 { public:string ID;//進(jìn)程名vector<int> UsedResource;//已用各資源數(shù)vector<int> NeedResource;//對(duì)應(yīng)的所需資源數(shù)Process&operator=(const Process &p) //運(yùn)算符重載用于賦值{if (this != &p){this->ID = p.ID;this->UsedResource = p.UsedResource;this->NeedResource = p.NeedResource;}return *this;} }; int ProcessCount;//進(jìn)程數(shù) int ResourceCount;//資源數(shù) vector<int>Available;//可用資源數(shù) vector<int>calc;//用于計(jì)算的資源vector list<Process> n;//進(jìn)程的鏈表 list<Process> Copy;//對(duì)于進(jìn)程鏈表的拷貝 list<Process> Copy_2;//對(duì)于進(jìn)程鏈表的拷貝 list<int>UsedResourceBuffer; list<int>NeedResourceBuffer; list<string> Safeyqueue;//安全序列 bool ShowQueue ()//顯示安全序列 {int a = 0;if (Safeyqueue.size()!= 0) {for (auto i=Safeyqueue.begin();i!=Safeyqueue.end();++i)//使用auto定義迭代器,設(shè)置循環(huán){cout << *i;if (a != (Safeyqueue.size ()-1)) {cout << "->";a++;}}return true;}else return false; } bool safetyCheak () {//安全性算法Safeyqueue.clear ();//清空SafeyqueueCopy_2.clear ();//清空Copy_2Copy_2 = Copy;int cheaknumber1=1;for (int i = ProcessCount; i > 0; i--){cheaknumber1 =cheaknumber1+i;}int cheaknumber2 = 0;while (1){int tip = 0;for (int b = 0; b < ResourceCount; b++){if (Copy_2.front ().NeedResource[b] <= calc[b]){tip++;//單個(gè)資源符合要求標(biāo)識(shí)符tip+1}}if (tip == ResourceCount)//進(jìn)程的所有資源均符合要求{for (int d = 0; d < ResourceCount; d++){calc[d] = calc[d] + Copy_2.front ().UsedResource[d];}cheaknumber2 = 0;Safeyqueue.push_back (Copy_2.front ().ID);Copy_2.pop_front ();}if (cheaknumber2 >= ProcessCount) break;//在第一次循環(huán)中就找不到符合條件的進(jìn)程,跳出循環(huán)else if (cheaknumber1 == 0) break;//循環(huán)數(shù)大于最大可能的循環(huán)數(shù),跳出循環(huán)else if (Copy_2.size () == 0) return true;Copy_2.push_back (Copy_2.front ());Copy_2.pop_front ();cheaknumber2++;cheaknumber1--;}return false; } Process SetProcess (string ID)//為進(jìn)程初始化所用的函數(shù) 返回進(jìn)程 {Process Buffer;//創(chuàng)建Process對(duì)象Buffer.ID = ID;//初始化IDwhile (UsedResourceBuffer.size() != 0)//若UsedResourceBuffer不為空{(diào)Buffer.UsedResource.push_back (UsedResourceBuffer.front ());//將UsedResourceBuffer的頭節(jié)點(diǎn)插入到對(duì)象UsdResource的尾部UsedResourceBuffer.pop_front ();//刪除UsedResourceBuffer的頭節(jié)點(diǎn)}while (NeedResourceBuffer.size () != 0)//方法與上相同{Buffer.NeedResource.push_back (NeedResourceBuffer.front ());NeedResourceBuffer.pop_front ();}return Buffer;//返回對(duì)象 } void ShowAllProcess ()//顯示全部進(jìn)程及資源表 {if (n.size () == 0) {cout << "無進(jìn)程,請(qǐng)分配進(jìn)程!" << endl;//n中無Process的對(duì)象return;}cout << std::left << setw (4) << "ID\t"<<std::right<< setw (12) << "USED\t\t" <<std::right<< setw (12) << " NEED\t" << endl<<std::left << setw (4) << "資源";for (int i = 1; i <= ResourceCount; i++){cout <<"\t" << std::left << i;}for (int i = 1; i <= ResourceCount; i++){cout <<"\t" << std::left << i ;}for (auto a = n.begin(); a != n.end (); ++a)//定義迭代器設(shè)置循環(huán){cout <<endl<<std::left <<setw (4) << a->ID<<"|\t";for (unsigned int b = 0;b<(a->UsedResource.size());b++){if(b!= (a->UsedResource.size ()-1))cout << setw (4) << a->UsedResource[b]<<"\t";else cout << setw (4) << a->UsedResource[b] << "|\t";}for (unsigned int b = 0; b<(a->NeedResource.size ()); b++){cout << setw (4) << a->NeedResource[b] << "\t";}} } int main () {while (1){system ("cls");system ("color F0");int choose;cout << "請(qǐng)輸入需要進(jìn)行的算法或需要進(jìn)行的操作\n""1.設(shè)置進(jìn)程個(gè)數(shù)\n""2.設(shè)置資源個(gè)數(shù)\n""3.為每個(gè)進(jìn)程分配資源\n""4.設(shè)置空閑資源并自動(dòng)檢測(cè)是否合法\n""5.執(zhí)行銀行家算法(請(qǐng)求新的資源)\n""6.查看當(dāng)前所有信息\n""7.清除所有內(nèi)容\n""8.退出程序\n";cout << "請(qǐng)輸入您的選擇:";cin >> choose;system ("cls");if (choose == 1){if (ProcessCount != 0) {cout << "您已輸入資源個(gè)數(shù),個(gè)數(shù)為" << ProcessCount << endl;cout << "若需更改必須清除全部數(shù)據(jù)" << endl;system ("pause");continue;}cout << "請(qǐng)輸入進(jìn)程個(gè)數(shù)(輸入錯(cuò)誤將會(huì)保持為零):";cin >> ProcessCount;if (ProcessCount <= 0) {cout << "輸入進(jìn)程數(shù)目錯(cuò)誤,請(qǐng)重試."<<endl;ProcessCount = 0;system ("pause");continue;}cout << "輸入進(jìn)程個(gè)數(shù)成功!"<<endl;system ("pause");}if (choose == 2){if (ResourceCount != 0) {cout << "您已輸入資源個(gè)數(shù),個(gè)數(shù)為" << ResourceCount << endl;cout << "若需更改必須清除全部數(shù)據(jù)" << endl;system ("pause");continue;}cout << "請(qǐng)輸入資源個(gè)數(shù)(輸入錯(cuò)誤將會(huì)保持為零):";cin >> ResourceCount;if (ResourceCount <= 0) {cout << "輸入資源個(gè)數(shù)錯(cuò)誤,請(qǐng)重試."<<endl;ResourceCount = 0;system ("pause");continue;}cout << "輸入資源個(gè)數(shù)成功!" << endl;system ("pause");}if (choose == 3){if ((ProcessCount == 0) || (ResourceCount == 0)) {cout << "請(qǐng)先分配資源和進(jìn)程再重試!" << endl;system ("pause");continue;}for (int i = 0; i < ProcessCount; i++){cout << "請(qǐng)輸入第"<<i+1<<"個(gè)進(jìn)程的ID:";string ID;cin >> ID;for (int i1 = 1; i1 <= ResourceCount; i1++){int a,b;cout << "請(qǐng)輸入第" << i+1 << "個(gè)進(jìn)程的第" << i1 << "個(gè)資源的占用數(shù)目:";while ((cin >> a) && (a < 0)){cout << endl<<"輸入不符合規(guī)則,請(qǐng)重試:";}cout << "請(qǐng)輸入第" << i + 1 << "個(gè)進(jìn)程的第" << i1 << "個(gè)資源的需求數(shù)目:";while ((cin >> b) && (b< 0)){cout << endl << "輸入不符合規(guī)則,請(qǐng)重試:";}UsedResourceBuffer.push_back (a);NeedResourceBuffer.push_back (b);}n.push_back(SetProcess (ID));}cout << endl << "當(dāng)前所有程序狀態(tài)如下\n";ShowAllProcess ();system ("pause");}if (choose == 4) {if ((ProcessCount == 0) || (ResourceCount == 0)) {cout << "請(qǐng)先分配資源和進(jìn)程再重試!" << endl;system ("pause");continue;}Available.clear ();for (int i = 0; i < ResourceCount; i++){int a;cout << "請(qǐng)?jiān)O(shè)置第" << i + 1 << "個(gè)資源的空閑個(gè)數(shù):";while ((cin >> a) && (a < 0)){cout <<endl<< "輸入數(shù)值不合法,請(qǐng)重試:";}Available.push_back (a);}calc.clear ();calc = Available;Copy.clear ();Copy = n;bool b=safetyCheak ();if (b == true) {cout << "當(dāng)前情況安全!"<<endl;cout << "可執(zhí)行的序列有(可能不唯一,這里只顯示一種):";ShowQueue ();system ("pause");continue;}if (b == false) {cout << "當(dāng)前情況不安全無法按當(dāng)前值設(shè)置空閑資源!"<<endl;cout << "請(qǐng)更改后重試!";Available.clear ();system ("pause");continue;}}if (choose == 5) {if ((ProcessCount == 0) || (ResourceCount == 0)) {cout << "請(qǐng)先分配資源和進(jìn)程再重試!" << endl;system ("pause");continue;}vector<int>buffer;//存儲(chǔ)當(dāng)前進(jìn)程請(qǐng)求的資源buffer.clear ();calc.clear ();calc=Available;Copy.clear ();Copy = n;string id;//顯示所有進(jìn)程狀態(tài)cout << "當(dāng)前資源情況如下:" << endl;ShowAllProcess ();cout << endl<<"當(dāng)前資源狀態(tài)如下" << endl;for (auto i = Available.begin(); i != Available.end (); ++i){cout << *i << "\t";}cout << endl << "請(qǐng)輸入需要資源的進(jìn)程名:";cin >> id;//對(duì)進(jìn)程進(jìn)行查找for (auto a = Copy.begin (); a != Copy.end (); ++a) {if (id == a->ID) {cout << endl << "找到此進(jìn)程!";cout << "請(qǐng)輸入目前是否需要分配資源,輸入-1取消分配其他數(shù)字繼續(xù):";int c; cin >> c;if (c == -1) {cout << "取消分配!"; system ("pause"); continue;}cout << "請(qǐng)輸入" << id << "進(jìn)程" << "需要的資源個(gè)數(shù):" << endl;//輸入當(dāng)前需要資源個(gè)數(shù)for (int d = 0; d < ResourceCount; d++){int e;cout << "請(qǐng)輸入第" << d+ 1 << "個(gè)資源個(gè)數(shù):";while ((cin >> e) &&( (e <0)||(e>a->NeedResource[d])||(e>calc[d]))){if (e < 0) cout << "輸入不符合規(guī)則";if (e > a->NeedResource[d]) cout << "輸入的數(shù)大于需要的資源數(shù)";if (e > calc[d]) cout << "輸入的數(shù)大于系統(tǒng)的資源數(shù)";cout<<",輸入錯(cuò)誤,請(qǐng)重試:" << endl;}a->UsedResource[d] = a->UsedResource[d] + e;a->NeedResource[d] = a->NeedResource[d] - e;calc[d] = calc[d] - e;buffer.push_back (e);}bool boolean = safetyCheak ();//執(zhí)行安全性算法檢測(cè)if (boolean == true) {int f;cout << "當(dāng)前情況安全!" << endl;cout << "是否要將資源賦給" << id << "?0確定,其他取消\n請(qǐng)輸入你的選擇:";cin >> f;if (f == 0) {//確定分配n.clear ();n = Copy;vector<int>buffer1;buffer1 = Available;Available.clear ();for (int b = 0; b < ResourceCount; b++){buffer1[b]=buffer1[b] - buffer[b];}Available = buffer1;cout << "本次已成功賦予資源!"<<endl;}else {cout << "已取消!"<<endl;}}if(boolean==false){cout << "不安全!因此無法分配!"<<endl;}cout <<endl<< "當(dāng)前進(jìn)程資源情況如下:\n";ShowAllProcess ();cout << endl<< "可用資源個(gè)數(shù)按順序分別為:";for (auto i = Available.begin (); i != Available.end (); ++i){cout << *i << " ";}cout <<endl <<"可執(zhí)行的隊(duì)列如下\n";ShowQueue ();system ("pause");continue;}}}if (choose == 6) {cout << "進(jìn)程個(gè)數(shù)為" << ProcessCount << endl;cout << "資源個(gè)數(shù)為" << ResourceCount << endl;cout << "可用資源個(gè)數(shù)按順序分別為:";for (auto i = Available.begin (); i != Available.end(); ++i){cout << *i<<" ";}cout << "當(dāng)前所有程序狀態(tài)如下\n";ShowAllProcess ();cout << endl;bool b=ShowQueue ();if(b==false)cout<<"沒有合適的可執(zhí)行隊(duì)列,請(qǐng)分配正確的資源!"<<endl;system ("pause");}if (choose == 7) {int a;cout << "確認(rèn)全部刪除么?刪除請(qǐng)輸入0"<<endl;cout << "請(qǐng)輸入:";cin >> a;if (a != 0) continue;ProcessCount=0;ResourceCount=0;Available.clear();n.clear();UsedResourceBuffer.clear();Safeyqueue.empty();cout << "全部刪除成功!";system ("pause");}if (choose == 8) {cout << "退出程序!\n";system ("pause");exit (0);}}return 0;}
總結(jié)
以上是生活随笔為你收集整理的操作系统课程设计--银行家算法的模拟实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(1545):模型和控制器
- 下一篇: Windows 终端常用命令,必备!