一、设计目的
1、了解多道系统中多个进程并发执行时的资源分配情况
2、掌握死锁产生的原因、必要条件和处理死锁的基本方法
3、掌握银行家算法,了解资源在进程并发执行中的分配策略
二、设计要求
设计一个n个并发进程共享m个资源的银行家算法的模拟实现。要求具有:
(1) 简单的交互界面
(2) 能显示当前系统资源的剩余情况和占用情况
(3) 能输入每个进程的最大资源要求
模拟利用银行家算法为进程的若干次资源请求分配资源
(4) 输入本次资源要求;
(5) 按银行家算法为进程分配资源,本次分配是否成功要显示出来(要能处理各种情况:可以满足这次请求、由于资源不够不能满足这次请求、由于可能产生不安全不能满足这次请求、请求不合理拒绝请求等)
(6) 作业撤销时要回收资源
Banker_Algorithm.h
- #ifndef _BANKER_ALGORITHM_H_
- #define _BANKER_ALGORITHM_H_
- class Banker_Algorithm
- {
- public:
- Banker_Algorithm(unsigned int pn,unsigned int rn);
- ~Banker_Algorithm();
- void init_Need();
- void request_Resource(unsigned int proc_no,unsigned int request_res[]);
- void callback(unsigned int proc_no);
- bool is_Safe();
- void disp_Available();
- void disp_Allocation();
- unsigned int **get_Max()
- {
- return max;
- }
- unsigned int *get_Available()
- {
- return available;
- }
- private:
- Banker_Algorithm(){}
- unsigned int proc_num;
- unsigned int resource_num;
- unsigned int **max;
- unsigned int **allocation;
- unsigned int **need;
- unsigned int *available;
- };
- #endif
Banker_Algorithm.cpp
- #include "Banker_Algorithm.h"
- #include <iostream>
- using std::cerr;
- using std::cout;
- using std::endl;
- Banker_Algorithm::Banker_Algorithm(unsigned int pn,unsigned int rn):proc_num(pn),resource_num(rn)
- {
- unsigned int i,j;
- max = new unsigned int*[pn];
- allocation = new unsigned int*[pn];
- need = new unsigned int*[pn];
- available = new unsigned int[rn];
- for(i = 0;i < proc_num;i++)
- {
- max[i] = new unsigned int[resource_num];
- allocation[i] = new unsigned int[resource_num];
- need[i] = new unsigned int[resource_num];
- for(j = 0;j < resource_num;j++)
- {
- allocation[i][j] = 0;
- }
- }
- }
- Banker_Algorithm::~Banker_Algorithm()
- {
- unsigned i;
- delete []available;
- for(i = 0;i < proc_num;i++)
- {
- delete []need[i];
- delete []allocation[i];
- delete []max[i];
- }
- delete need;
- delete allocation;
- delete max;
- }
- void Banker_Algorithm::init_Need()
- {
- unsigned int i,j;
- for(i = 0;i < proc_num;i++)
- {
- for(j = 0;j < resource_num;j++)
- {
- need[i][j] = max[i][j];
- }
- }
- }
- void Banker_Algorithm::request_Resource(unsigned int proc_no,unsigned int request_res[])
- {
- unsigned int i;
- if(proc_no > proc_num)
- {
- cerr<<"WRONG PROCESS NO,REQUEST FAILED"<<endl;
- return;
- }
- for(i = 0;i < resource_num;i++)
- {
- if(request_res[i] > need[proc_no - 1][i])
- {
- cerr<<"THE NO "<<i + 1<<" REQUEST RESOURCE NUMBER IS BEYOND THE NEED OF THIS PROCESS"<<endl;
- cerr<<"REQUEST FAILED"<<endl;
- return;
- }
- if(request_res[i] > available[i])
- {
- cerr<<"THE NO "<<i + 1<<" REQUEST RESOURCE NUMBER IS BEYOND THE AVAILABLE RESOURCE"<<endl;
- cerr<<"REQUEST FAILED"<<endl;
- return;
- }
- }
- for(i = 0;i < resource_num;i++)
- {
- available[i] -= request_res[i];
- allocation[proc_no - 1][i] += request_res[i];
- need[proc_no][i] -= request_res[i];
- }
- if(is_Safe())
- {
- cout<<"ALLOCATION SUCCESS"<<endl;
- }
- else
- {
- for(i = 0;i < resource_num;i++)
- {
- available[i] += request_res[i];
- allocation[proc_no - 1][i] -= request_res[i];
- need[proc_no][i] += request_res[i];
- }
- cerr<<"NOT SAFE!ALLOCATION FAILED"<<endl;
- }
- }
- void Banker_Algorithm::callback(unsigned int proc_no)
- {
- unsigned int i;
- if(proc_no > proc_num)
- {
- cerr<<"WRONG PROCESS NO,REQUEST FAILED"<<endl;
- return;
- }
- for(i = 0;i < resource_num;i++)
- {
- available[i] += allocation[proc_no - 1][i];
- allocation[proc_no - 1][i] = 0;
- need[proc_no - 1][i] = max[proc_no][i];
- }
- cout<<"CALLBACK SUCCESS"<<endl;
- }
- bool Banker_Algorithm::is_Safe()
- {
- int i;
- unsigned int work[resource_num],safe_seq[proc_num],j,safe_seq_index = 0;
- bool finish[proc_num],is_safe,is_fit;
- for(i = 0;static_cast<unsigned int>(i) < proc_num;i++)
- {
- finish[i] = false;
- }
- for(i = 0;static_cast<unsigned int>(i) < resource_num;i++)
- {
- work[i] = available[i];
- }
- i = 0;
- for(;static_cast<unsigned int>(i) < proc_num;i++)
- {
- is_fit = true;
- if(!finish[i])
- {
- for(j = 0;j < resource_num;j++)
- {
- if(need[i][j] > work[j])
- {
- is_fit = false;
- break;
- }
- }
- if(is_fit)
- {
- for(j = 0;j < resource_num;j++)
- {
- work[j] += allocation[i][j];
- }
- finish[i] = true;
- safe_seq[safe_seq_index++] = i + 1;
- i = -1;
- }
- }
- else
- {
- is_safe = true;
- for(j = 0;j < proc_num;j++)
- {
- if(!finish[j])
- {
- is_safe = false;
- break;
- }
- }
- if(is_safe)
- {
- cout<<"SAFE SEQUENCE:";
- for(j = 0;j < proc_num;j++)
- {
- cout<<safe_seq[j]<<" ";
- }
- cout<<endl;
- return true;
- }
- }
- }
- return false;
- }
- void Banker_Algorithm::disp_Available()
- {
- unsigned int i;
- cout<<"AVAILABLE RESOURCE STATUS"<<endl;
- for(i = 0;i < resource_num;i++)
- {
- cout<<"NO "<<i + 1<<":"<<available[i]<<endl;
- }
- }
- void Banker_Algorithm::disp_Allocation()
- {
- unsigned int i,j;
- cout<<"ALLOCATION STATUS"<<endl;
- for(i = 0;i < proc_num;i++)
- {
- cout<<"PROCESS "<<i + 1;
- for(j = 0;j < resource_num;j++)
- {
- cout<<" RES NO "<<j<<":"<<allocation[i][j]<<" ";
- }
- cout<<endl;
- }
- }
main.cpp
- #include <iostream>
- #include "Banker_Algorithm.h"
- using namespace std;
- int main()
- {
- cout<<"OS BIG WORK NO 2 BY MARCUSXING 2009 12 12"<<endl;
- cout<<"****************************************"<<endl;
- cout<<"please enter the process number:";
- unsigned int proc_num,res_num;
- cin>>proc_num;
- cout<<"please enter the resource number:";
- cin>>res_num;
- Banker_Algorithm ba(proc_num,res_num);
- unsigned int max,avai,i,j;
- for(i = 0;i < proc_num;i++)
- {
- for(j = 0;j < res_num;j++)
- {
- cout<<"please enter No "<<i + 1<<" process No "<<j + 1<<" resource max:";
- cin>>max;
- ba.get_Max()[i][j] = max;
- }
- }
- for(j = 0;j < res_num;j++)
- {
- cout<<"please enter No "<<j + 1<<" resource available number:";
- cin>>avai;
- ba.get_Available()[j] = avai;
- }
- ba.init_Need();
- unsigned int proc_no,req_array[res_num];
- char c;
- bool flag = true;
- //ba.request_Resource();
- if(ba.is_Safe())
- {
- cout<<"****************************************"<<endl;
- cout<<"please select a number to do something"<<endl;
- cout<<"h:help message"<<endl;
- cout<<"1:request resource"<<endl;
- cout<<"2:callback resource of a process"<<endl;
- cout<<"3:display available resource status"<<endl;
- cout<<"4:display allocation status"<<endl;
- cout<<"q:quit"<<endl;
- while(flag)
- {
- cout<<"please enter your choice:";
- if(!cin)
- {
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- }
- cin>>c;
- switch(c)
- {
- case '1':
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- cout<<"please enter the process No:";
- cin>>proc_no;
- for(j = 0;j < res_num;j++)
- {
- cout<<"please enter the No "<<j + 1<<" resource request number:";
- cin>>req_array[j];
- }
- ba.request_Resource(proc_no - 1,req_array);
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- break;
- case '2':
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- cout<<"please enter the process No:";
- cin>>proc_no;
- ba.callback(proc_no);
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- break;
- case '3':
- ba.disp_Available();
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- break;
- case '4':
- ba.disp_Allocation();
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- break;
- case 'q':
- flag = false;
- break;
- case 'h':
- cin.ignore(numeric_limits<streamsize>::max(),'/n');
- cout<<"****************************************"<<endl;
- cout<<"please select a number to do something"<<endl;
- cout<<"h:help message"<<endl;
- cout<<"2:callback resource of a process"<<endl;
- cout<<"1:request resource"<<endl;
- cout<<"2:display available resource status"<<endl;
- cout<<"3:display allocation status"<<endl;
- cout<<"q:quit"<<endl;
- break;
- default:
- cout<<"are you kidding me?"<<endl;
- return -1;
- break;
- }
- }
- }
- else
- {
- cerr<<"NOT SAFE"<<endl;
- return -1;
- }
- return 0;
- }