编程实现银行家算法:避免死锁与安全序列分析

需积分: 10 5 下载量 48 浏览量 更新于2024-09-10 收藏 254KB DOC 举报
"这篇实验报告详细介绍了如何编程实现银行家算法,旨在理解并避免死锁,同时要求输出进程的安全序列。学生需要完成设计说明、代码实现、运行结果展示,并通过实验加深对银行家算法的理解。实验步骤包括分析算法结构、绘制流程图、编写和检查代码。报告中还给出了实验数据和处理结果,以及实验体会和参考资料。" 银行家算法是一种著名的预防死锁的策略,由艾兹格·迪杰斯特拉提出。它模拟了银行家如何管理贷款以避免金融危机的情况,以此来确保操作系统中的资源分配不会导致死锁。在操作系统中,多个进程可能会并发请求资源,如果不加以控制,可能导致所有进程都无法继续执行,即形成死锁。 银行家算法的核心在于"安全性"概念,即存在一个安全序列,使得按照这个序列分配资源,所有进程都可以顺利执行并完成,而不会导致资源耗尽。安全序列是指能够保证系统不发生死锁的一种进程执行顺序。 实验内容要求学生理解避免死锁的方法,明白死锁与安全序列之间的关系。在编程实现中,主要包括以下几个关键部分: 1. 输入初始数据:定义系统资源总量和每个进程已分配和需要的资源。 2. 输出当前状态:展示当前资源分配情况,以便观察系统状态。 3. 资源变更:当进程请求资源且满足条件时,更新资源分配。 4. 安全性检查:通过算法检查是否存在安全序列,如果存在,则可以安全地分配资源;否则,拒绝请求以防止死锁。 5. 输出安全序列:找到安全序列后,输出该序列,表明系统可以避免死锁。 实验报告中提到,程序由主函数和其他辅助函数组成,如输入处理、输出显示、资源分配变化、安全检查和安全序列输出等。在实际编码过程中,需要细致入微,因为即使是小错误也可能导致整个程序无法正常工作。通过实验,学生可以锻炼分析能力和编程技巧,提高解决问题的能力。 实验体会部分强调了编程实践中的挑战,如查找和修复错误、调试和优化代码的重要性。同时,清晰的用户界面和说明对于其他人理解和使用程序至关重要。 参考资料包括《计算机操作系统》、《C程序设计》和《C语言程序设计_现代方法》,这些都是学习操作系统和编程基础的重要书籍。 银行家算法的实现是一个理论与实践相结合的过程,有助于深入理解操作系统中的并发控制和死锁预防策略。
2010-04-10 上传
#pragma once #include "Processor.h" #include <iostream> using namespace std; class Control { private : Processor * progress; int num; int *Available; public: Control(int n,int *A,int m) { num=n; Available=A; progress=new Processor [num]; string na=""; cout<<"请依次输入各个进程的名字及其资源的最大需求量:"<<endl; for(int i=0;i<num;i++) { cin>>na; int *temp=new int [num]; for(int j=0;j<m;j++) { cin>>temp[j]; } progress[i].Change(m,temp,na); } } void Distribute() { int n=0; while(!Allover()) { int i=n%num; n++; if(!progress[i].Finish) { cout<<"当前进程名:"<<progress[i].name<<endl; progress[i].Request(); cout<<"资源请求:"; for(int j=0;j<progress[i].num;j++) { cout<<progress[i].Req[j]<<" "; } cout<<"资源需要:"; for(int j=0;j<progress[i].num;j++) { cout<<progress[i].Need[j]<<" "; } cout<<endl; if(Finderror(i)) { for(int j=0;j<progress[i].num;j++) { Available[j]=Available[j]-progress[i].Req[j]; progress[i].Allocation[j]=progress[i].Allocation[j]+progress[i].Req[j]; progress[i].Need[j]=progress[i].Need[j]-progress[i].Req[j]; } if(Isover(i)) { progress[i].Finish=true; for(int k=0;k<progress[i].num;k++) { Available[k]=Available[k]+progress[i].Max[k]; } cout<<progress[i].name<<"进程运行结束!"<<endl; } if(!Detecting()) { for(int j=0;j<progress[i].num;j++) { Available[j]=Available[j]+progress[i].Req[j]; progress[i].Allocation[j]=progress[i].Allocation[j]-progress[i].Req[j]; progress[i].Need[j]=progress[i].Need[j]+progress[i].Req[j]; } cout<<"会出现死锁,请求被驳回。进程被暂停!执行下一进程……"<<endl; } } else { cout<<"请求资源出错!进程被暂停!执行下一进程……"<<endl; } } } cout<<"进程全部运行结束!"<<endl; } bool Finderror(int n)//判断请求是否错误 { for(int i=0;i<progress[n].num;i++) { if(progress[n].Need[i]<progress[n].Req[i]) { return false; } } return true; } bool Detecting()//死锁检测 { string name=""; int *Work=new int [progress[0].num]; bool *Finish=new bool [num]; for(int i=0;i<progress[0].num;i++) { Work[i]=Available[i]; } for(int i=0;i<num;i++) { Finish[i]=progress[i].Finish; } int m=num; int n=0; while(m) { int temp=n%num; if(!Finish[temp]) { if(compare(temp,Work)) { Finish[temp]=true; name=name+progress[temp].name+" "; for(int i=0;i<progress[0].num;i++) { Work[i]=Work[i]+progress[temp].Allocation[i]; } m=num; } } n++; m--; } for(int i=0;i<num;i++) { if(!Finish[i]) { return false; } } cout<<"安全序列:"<<name<<endl; return true; } bool compare(int n,int *Work)// { for(int i=0;i<progress[n].num;i++) { if(progress[n].Need[i]>Work[i]) { return false; } } return true; } bool Isover(int n)//判断进程是否可以执行结束 { for(int i=0;i<progress[n].num;i++) { if(progress[n].Allocation[i]!=progress[n].Max[i]) { return false; } } return true; } bool Allover()//判断所有进程是否已执行结束 { for(int i=0;i<num;i++) { if(!progress[i].Finish) { return false; } } return true; } void Display(int n,int * temp) { for(int i=0;i<n;i++) { cout<<temp[i]<<" "; } } public: ~Control(void) { } }; 环境:Visual Studio 2005