操作系统课程设计--银行家算法的模拟实现

2019-04-13 15:59发布

发一些大三操作系统的实验代码吸引阅读量吧,当时做实验的时候看见网上很多人写的代码并不好,而且很多人都有错误的地方。如果好的话希望能点赞关注。 本篇文章选自课程设计报告的部分,所以相比前两篇实验详细很多,我尽量贴一些重要的部分出来 在多道程序系统中,多个进程在运行中对于资源的争夺而造成了一种僵局—死锁,若无外力作用,则这些进程均无法向前推进。如此,寻求避免死锁的方法就显得尤为重要。死锁产生的原因一般有三种:竞争不可抢占性资源、竞争可消耗性资源、进程的推进顺序不当。因此,在当前有限资源下,找到一组合法的顺序(称之为安全序列)执行,便能有效的避免死锁的产生。银行家算法便是最有代表性的避免死锁的算法,它是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。本次课程设计通过设计并编写程序来模拟银行家算法的执行过程。 一、数据结构的选择 a.将每个进程都视作一个对象,因此使用类进行存储和读取,并重载运算符用于数据的拷贝。为了实现资源数的可变性,则使用STL(Standard Template Library标准模板库,C++的一部分)中的vector容器存储各资源已用的资源和需要的资源数(int型)。类的定义如下所示: class Process//使用一个类的对象表示一个进程 {public: stringID;//进程名 vectorUsedResource;//已用各资源数 vectorNeedResource;//对应的所需资源数 Process&operator=(constProcess &p) //运算符重载用于赋值 { if(this != &p) { this->ID= p.ID; this->UsedResource= p.UsedResource; this->NeedResource= p.NeedResource; } return*this; } };

b.为了对进程数和资源数进行存储,分别定义了int型变量ProcessCount、ResourceCount用于存储进程数和资源数。 c.为了对各资源的可用资源数进行存储和读取,定义了vectorAvailable用于存储可用资源数。 d.为了存储各进程的信息,使用对象的list,即STL中的链表list n。 e.因为在安全性算法运算时需要更改进程中的资源信息和当前可用资源信息,所以分别定义了list Copy、list Copy_2、vectorcalc在运算前对当前进程的链表和当前资源信息进行拷贝,并用以运算。 f.因为对进程的初始化较为繁琐,所以定义了listUsedResourceBuffer、listNeedResourceBuffer用于对Process的初始化。 g.定义了listSafeyqueue用于存储安全序列。 二、模块的划分 由于算法规模较小,所以大多数的实现均将其写在main函数中的while循环体中,需要使用的变量等也尽量定义为全局变量。但在选择后分别完成了不同的且重要的功能。除main函数中的部分,其它单独出的模块的功能如下: a.SetProcess:对单个进程的信息进行初始化,返回初始化完成的进程对象。 b.ShowAllProcess:对所有进程进行显示 c.safetyCheak:用于安全性算法,并对安全序列进行初始化 d.ShowQueue:显示安全序列的情况。
三、实现代码如下 #include #include #include #include #include #include using namespace std; class Process//使用一个类的对象表示一个进程 { public: string ID;//进程名 vector UsedResource;//已用各资源数 vector NeedResource;//对应的所需资源数 Process&operator=(const Process &p) //运算符重载用于赋值 { if (this != &p) { this->ID = p.ID; this->UsedResource = p.UsedResource; this->NeedResource = p.NeedResource; } return *this; } }; int ProcessCount;//进程数 int ResourceCount;//资源数 vectorAvailable;//可用资源数 vectorcalc;//用于计算的资源vector list n;//进程的链表 list Copy;//对于进程链表的拷贝 list Copy_2;//对于进程链表的拷贝 listUsedResourceBuffer; listNeedResourceBuffer; list Safeyqueue;//安全序列 bool ShowQueue ()//显示安全序列 { int a = 0; if (Safeyqueue.size()!= 0) { for (auto i=Safeyqueue.begin();i!=Safeyqueue.end();++i)//使用auto定义迭代器,设置循环 { cout << *i; if (a != (Safeyqueue.size ()-1)) { cout << "->"; a++; } } return true; } else return false; } bool safetyCheak () {//安全性算法 Safeyqueue.clear ();//清空Safeyqueue Copy_2.clear ();//清空Copy_2 Copy_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++;//单个资源符合要求标识符tip+1 } } if (tip == ResourceCount)//进程的所有资源均符合要求 { 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;//在第一次循环中就找不到符合条件的进程,跳出循环 else if (cheaknumber1 == 0) break;//循环数大于最大可能的循环数,跳出循环 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)//为进程初始化所用的函数 返回进程 { Process Buffer;//创建Process对象 Buffer.ID = ID;//初始化ID while (UsedResourceBuffer.size() != 0)//若UsedResourceBuffer不为空 { Buffer.UsedResource.push_back (UsedResourceBuffer.front ());//将UsedResourceBuffer的头节点插入到对象UsdResource的尾部 UsedResourceBuffer.pop_front ();//删除UsedResourceBuffer的头节点 } while (NeedResourceBuffer.size () != 0)//方法与上相同 { Buffer.NeedResource.push_back (NeedResourceBuffer.front ()); NeedResourceBuffer.pop_front (); } return Buffer;//返回对象 } void ShowAllProcess ()//显示全部进程及资源表 { if (n.size () == 0) { cout << "无进程,请分配进程!" << endl;//n中无Process的对象 return; } cout << std::left << setw (4) << "ID "<ID<<"| "; for (unsigned int b = 0;b<(a->UsedResource.size());b++) {if(b!= (a->UsedResource.size ()-1)) cout << setw (4) << a->UsedResource[b]<<" "; else cout << setw (4) << a->UsedResource[b] << "| "; } for (unsigned int b = 0; b<(a->NeedResource.size ()); b++) { cout << setw (4) << a->NeedResource[b] << " "; } } } int main () { while (1) { system ("cls"); system ("color F0"); int choose; cout << "请输入需要进行的算法或需要进行的操作 " "1.设置进程个数 ""2.设置资源个数 ""3.为每个进程分配资源 ""4.设置空闲资源并自动检测是否合法 ""5.执行银行家算法(请求新的资源) ""6.查看当前所有信息 ""7.清除所有内容 ""8.退出程序 "; cout << "请输入您的选择:"; cin >> choose; system ("cls"); if (choose == 1) { if (ProcessCount != 0) { cout << "您已输入资源个数,个数为" << ProcessCount << endl; cout << "若需更改必须清除全部数据" << endl; system ("pause"); continue; } cout << "请输入进程个数(输入错误将会保持为零):"; cin >> ProcessCount; if (ProcessCount <= 0) { cout << "输入进程数目错误,请重试."<> ResourceCount; if (ResourceCount <= 0) { cout << "输入资源个数错误,请重试."<> ID; for (int i1 = 1; i1 <= ResourceCount; i1++) { int a,b; cout << "请输入第" << i+1 << "个进程的第" << i1 << "个资源的占用数目:"; while ((cin >> a) && (a < 0)) { cout << endl<<"输入不符合规则,请重试:"; } cout << "请输入第" << i + 1 << "个进程的第" << i1 << "个资源的需求数目:"; while ((cin >> b) && (b< 0)) { cout << endl << "输入不符合规则,请重试:"; } UsedResourceBuffer.push_back (a); NeedResourceBuffer.push_back (b); } n.push_back(SetProcess (ID)); } cout << endl << "当前所有程序状态如下 "; ShowAllProcess (); system ("pause"); } if (choose == 4) { if ((ProcessCount == 0) || (ResourceCount == 0)) { cout << "请先分配资源和进程再重试!" << endl; system ("pause"); continue; } Available.clear (); for (int i = 0; i < ResourceCount; i++) { int a; cout << "请设置第" << i + 1 << "个资源的空闲个数:"; while ((cin >> a) && (a < 0)) { cout <buffer;//存储当前进程请求的资源 buffer.clear (); calc.clear (); calc=Available; Copy.clear (); Copy = n; string id; //显示所有进程状态 cout << "当前资源情况如下:" << endl; ShowAllProcess (); cout << endl<<"当前资源状态如下" << endl; for (auto i = Available.begin(); i != Available.end (); ++i) { cout << *i << " "; } cout << endl << "请输入需要资源的进程名:"; cin >> id; //对进程进行查找 for (auto a = Copy.begin (); a != Copy.end (); ++a) { if (id == a->ID) { cout << endl << "找到此进程!"; cout << "请输入目前是否需要分配资源,输入-1取消分配其他数字继续:"; int c; cin >> c; if (c == -1) { cout << "取消分配!"; system ("pause"); continue; } cout << "请输入" << id << "进程" << "需要的资源个数:" << endl; //输入当前需要资源个数 for (int d = 0; d < ResourceCount; d++) { int e; cout << "请输入第" << d+ 1 << "个资源个数:"; while ((cin >> e) &&( (e <0)||(e>a->NeedResource[d])||(e>calc[d]))){ if (e < 0) cout << "输入不符合规则"; if (e > a->NeedResource[d]) cout << "输入的数大于需要的资源数"; if (e > calc[d]) cout << "输入的数大于系统的资源数"; cout<<",输入错误,请重试:" << 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 ();//执行安全性算法检测 if (boolean == true) { int f; cout << "当前情况安全!" << endl; cout << "是否要将资源赋给" << id << "?0确定,其他取消 请输入你的选择:"; cin >> f; if (f == 0) {//确定分配 n.clear (); n = Copy; vectorbuffer1; buffer1 = Available; Available.clear (); for (int b = 0; b < ResourceCount; b++) { buffer1[b]=buffer1[b] - buffer[b]; } Available = buffer1; cout << "本次已成功赋予资源!"<> a; if (a != 0) continue; ProcessCount=0; ResourceCount=0; Available.clear(); n.clear(); UsedResourceBuffer.clear(); Safeyqueue.empty(); cout << "全部删除成功!"; system ("pause"); } if (choose == 8) { cout << "退出程序! "; system ("pause"); exit (0); } } return 0; }