用银行家算法实现系统资源分配
2012-03-11 23:22
246 查看
银行家算法是Dijkstra在1965年提出的一种避免死锁的算法。银行家算法陈述如下:
1) 当一个进程提出一个资源的请求时,假定分配给它,并调用检查系统状态安全性的算法。如果系统是安全的,则对申请者的假分配变为实际的分配。否则,推迟它的请求,让其阻塞等待。
2) 检查系统状态安全性的算法。根据系统剩余的资源情况,银行家进行检查,看满足请求者的要求后,是否仍是系统中的所有进程都能正常完成(即能找到一个进程完成序列)。若能,系统是安全的。否则,系统是不安全的。
银行家算法主要如下:
输入:资源个数m、进程个数n、最大请求矩阵max、分配矩阵allocation
输出:进程运行情况和安全状况提示(如果安全,输出一个可能的进程完成序列)
主要算法:
1) 初始化,输入各个参数,初始化各变量
2) 判断系统安全性
程序中安全性算法的描述如下:
a. 设置如下两个工作向量:
Work:表示系统可提供给进程继续运行的各类资源的空闲资源数目,它含有m个元素,执行安全性算法开始时,Work=Available。
Finish:表示系统是否有足够的资源分配给进程,使之运行完成。开始时,Finish[i]=false;当有足够的资源分配给进程Pi时,令Finish[i]=true。
b. 从进程集合中找到一个能满足下列条件的进程:
Finish[i]= false;
Need[i] <= Work;
如果找到了就执行步骤c,否则执行步骤d。
c. 当进程Pi获得资源后,可执行直到完成,并释放出分配给它的资源,故应执行
Work = Allocation[i]+Work;
Finish[i]=true;
然后转向b。
d. 若所有进程中的Finish[i]都是true,则表示系统处于安全状态;否则,系统处于不安全状态。
3) 当系统请求资源时,调用系统状态安全性算法
系统状态安全性算法:
当某一进程提出资源申请时,系统须做出判断,能否将所申请资源分配给该进程。设Request[i]是进程Pi的请求向量,Request[i][j]=k表示进程Pi请求分配 j类资源有k个。当Pi发出资源请求后,系统按照下述步骤进行检查:
a. 如果Request[i]<= Need[i],则转向b;否则出错,因为进程所需要的资源数已超过它所宣布的最大值;
b. 如果Request[i]<=Available,则转向步骤c;否则,表示系统中尚无足够的资源满足进程Pi的申请,让进程Pi等待。
c. 假设系统把申请的资源分配给进程Pi,则对应下面的数据结构进行修改:
Available= Available-Request[i];
Allocation[i]= Allocation[i]+Request[i];
Need[i]= Need[i]-Request[i];
d. 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,就将资源分配给Pi,满足其资源申请要求;否则,让进程等待,并恢复原来的资源分配状态。
数据结构:
class bank
{
private:
int m; //资源数量
int n; //进程数量
int available[M]; //可利用资源向量
int max[M]
; //最大需求矩阵
int allocation[M]
; //分配矩阵
int need[M]
; //需求矩阵
public:
bool Initilize(); //初始化各变量
bool IsSafe(); //检查系统是否安全
bool Resoure_allocate();//分配资源
bool IsFinish(); //检查系统是否运行完毕
};
测试用例:
本测试用例为《操作系统原理教程(第二版)》P62页用例,先给P2分配一个打印机,分配成功,然后分配给P5一台打印机,分配失败,然后按照P4,P1,P5,P2,P3执行系统。
Available=(1,0,2,0)
[align=center]进程当前的分配矩阵Allocation[/align]
[align=center]进程当前的剩余请求矩阵Need[/align]
[align=center]各个进程的最大请求矩阵Max[/align]
测试数据:(直接复制到终端中即可)
4
5
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
1 0 2 0
1
2
1
4
2
1
3
2
1
0
0
1
0
1
1
4
0
2
4
1
1
4
2
1
1
1
1
1
3
2
2
0
3
2
1
1
运行结果:
输入资源数量:4
输入进程数量:5
输入最大请求矩阵 5X4
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
输入分配矩阵 5X4
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
输入可利用资源向量 1X4
1 0 2 0
安全序列是
3 0 1 2 4
输入运行进程号:1
请求资源号:2
请求数量:1
安全序列是
3 0 1 2 4
输入运行进程号:4
请求资源号:2
请求数量:1
没有安全序列
系统不安全,等待
输入运行进程号:3
请求资源号:2
请求数量:1
安全序列是
0 1 2 4
进程3运行完毕
输入运行进程号:0
请求资源号:0
请求数量:1
安全序列是
0 1 2 4
输入运行进程号:0
请求资源号:1
请求数量:1
安全序列是
1 2 4
进程0运行完毕
输入运行进程号:4
请求资源号:0
请求数量:2
安全序列是
1 2 4
输入运行进程号:4
请求资源号:1
请求数量:1
安全序列是
4 1 2
输入运行进程号:4
请求资源号:2
请求数量:1
安全序列是
1 2
进程4运行完毕
输入运行进程号:1
请求资源号:1
请求数量:1
安全序列是
1 2
输入运行进程号:1
请求资源号:3
请求数量:2
安全序列是
2
进程1运行完毕
输入运行进程号:2
请求资源号:0
请求数量:3
安全序列是
2
输入运行进程号:2
请求资源号:1
请求数量:1
安全序列是
进程2运行完毕
所有进程执行完毕
本文出自 “天才鸟蛋” 博客,请务必保留此出处http://curley.blog.51cto.com/1627940/803342
1) 当一个进程提出一个资源的请求时,假定分配给它,并调用检查系统状态安全性的算法。如果系统是安全的,则对申请者的假分配变为实际的分配。否则,推迟它的请求,让其阻塞等待。
2) 检查系统状态安全性的算法。根据系统剩余的资源情况,银行家进行检查,看满足请求者的要求后,是否仍是系统中的所有进程都能正常完成(即能找到一个进程完成序列)。若能,系统是安全的。否则,系统是不安全的。
银行家算法主要如下:
输入:资源个数m、进程个数n、最大请求矩阵max、分配矩阵allocation
输出:进程运行情况和安全状况提示(如果安全,输出一个可能的进程完成序列)
主要算法:
1) 初始化,输入各个参数,初始化各变量
2) 判断系统安全性
程序中安全性算法的描述如下:
a. 设置如下两个工作向量:
Work:表示系统可提供给进程继续运行的各类资源的空闲资源数目,它含有m个元素,执行安全性算法开始时,Work=Available。
Finish:表示系统是否有足够的资源分配给进程,使之运行完成。开始时,Finish[i]=false;当有足够的资源分配给进程Pi时,令Finish[i]=true。
b. 从进程集合中找到一个能满足下列条件的进程:
Finish[i]= false;
Need[i] <= Work;
如果找到了就执行步骤c,否则执行步骤d。
c. 当进程Pi获得资源后,可执行直到完成,并释放出分配给它的资源,故应执行
Work = Allocation[i]+Work;
Finish[i]=true;
然后转向b。
d. 若所有进程中的Finish[i]都是true,则表示系统处于安全状态;否则,系统处于不安全状态。
3) 当系统请求资源时,调用系统状态安全性算法
系统状态安全性算法:
当某一进程提出资源申请时,系统须做出判断,能否将所申请资源分配给该进程。设Request[i]是进程Pi的请求向量,Request[i][j]=k表示进程Pi请求分配 j类资源有k个。当Pi发出资源请求后,系统按照下述步骤进行检查:
a. 如果Request[i]<= Need[i],则转向b;否则出错,因为进程所需要的资源数已超过它所宣布的最大值;
b. 如果Request[i]<=Available,则转向步骤c;否则,表示系统中尚无足够的资源满足进程Pi的申请,让进程Pi等待。
c. 假设系统把申请的资源分配给进程Pi,则对应下面的数据结构进行修改:
Available= Available-Request[i];
Allocation[i]= Allocation[i]+Request[i];
Need[i]= Need[i]-Request[i];
d. 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,就将资源分配给Pi,满足其资源申请要求;否则,让进程等待,并恢复原来的资源分配状态。
数据结构:
class bank
{
private:
int m; //资源数量
int n; //进程数量
int available[M]; //可利用资源向量
int max[M]
; //最大需求矩阵
int allocation[M]
; //分配矩阵
int need[M]
; //需求矩阵
public:
bool Initilize(); //初始化各变量
bool IsSafe(); //检查系统是否安全
bool Resoure_allocate();//分配资源
bool IsFinish(); //检查系统是否运行完毕
};
测试用例:
本测试用例为《操作系统原理教程(第二版)》P62页用例,先给P2分配一个打印机,分配成功,然后分配给P5一台打印机,分配失败,然后按照P4,P1,P5,P2,P3执行系统。
Available=(1,0,2,0)
进程 | 磁带机 | 绘图机 | 打印机 | 光驱 |
P1 | 3 | 0 | 1 | 1 |
P2 | 0 | 1 | 0 | 0 |
P3 | 1 | 1 | 1 | 0 |
P4 | 1 | 1 | 0 | 1 |
P5 | 0 | 0 | 0 | 0 |
进程 | 磁带机 | 绘图机 | 打印机 | 光驱 |
P1 | 1 | 1 | 0 | 0 |
P2 | 0 | 1 | 1 | 2 |
P3 | 3 | 1 | 0 | 0 |
P4 | 0 | 0 | 1 | 0 |
P5 | 2 | 1 | 1 | 0 |
进程 | 磁带机 | 绘图机 | 打印机 | 光驱 |
P1 | 4 | 1 | 1 | 1 |
P2 | 0 | 2 | 1 | 2 |
P3 | 4 | 2 | 1 | 0 |
P4 | 1 | 1 | 1 | 1 |
P5 | 2 | 1 | 1 | 0 |
测试数据:(直接复制到终端中即可)
4
5
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
1 0 2 0
1
2
1
4
2
1
3
2
1
0
0
1
0
1
1
4
0
2
4
1
1
4
2
1
1
1
1
1
3
2
2
0
3
2
1
1
运行结果:
输入资源数量:4
输入进程数量:5
输入最大请求矩阵 5X4
4 1 1 1
0 2 1 2
4 2 1 0
1 1 1 1
2 1 1 0
输入分配矩阵 5X4
3 0 1 1
0 1 0 0
1 1 1 0
1 1 0 1
0 0 0 0
输入可利用资源向量 1X4
1 0 2 0
安全序列是
3 0 1 2 4
输入运行进程号:1
请求资源号:2
请求数量:1
安全序列是
3 0 1 2 4
输入运行进程号:4
请求资源号:2
请求数量:1
没有安全序列
系统不安全,等待
输入运行进程号:3
请求资源号:2
请求数量:1
安全序列是
0 1 2 4
进程3运行完毕
输入运行进程号:0
请求资源号:0
请求数量:1
安全序列是
0 1 2 4
输入运行进程号:0
请求资源号:1
请求数量:1
安全序列是
1 2 4
进程0运行完毕
输入运行进程号:4
请求资源号:0
请求数量:2
安全序列是
1 2 4
输入运行进程号:4
请求资源号:1
请求数量:1
安全序列是
4 1 2
输入运行进程号:4
请求资源号:2
请求数量:1
安全序列是
1 2
进程4运行完毕
输入运行进程号:1
请求资源号:1
请求数量:1
安全序列是
1 2
输入运行进程号:1
请求资源号:3
请求数量:2
安全序列是
2
进程1运行完毕
输入运行进程号:2
请求资源号:0
请求数量:3
安全序列是
2
输入运行进程号:2
请求资源号:1
请求数量:1
安全序列是
进程2运行完毕
所有进程执行完毕
#include <iostream> #include <cstdlib> #define M 16 #define N 16 using namespace std; class bank { private: int m; //资源数量 int n; //进程数量 int available[M]; //可利用资源向量 int max[M] ; //最大需求矩阵 int allocation[M] ; //分配矩阵 int need[M] ; //需求矩阵 public: bool Initilize(); //初始化各变量 bool IsSafe(); //检查系统是否安全 bool Resoure_allocate();//分配资源 bool IsFinish(); //检查系统是否运行完毕 }; int main() { bank process; if (!process.Initilize()) //初始化 { cout<<"输入错误"<<endl; } if (!process.IsSafe()) //检查系统运行初是否安全 { return 0; } while (true) { process.Resoure_allocate(); //根据各进程需要分配资源 if (process.IsFinish()) //检查系统是否执行完毕 { cout<<"所有进程执行完毕"<<endl; break; } } system("PAUSE"); return 0; } bool bank::Initilize() { int i,j; cout<<"输入资源数量:"; cin>>m; cout<<"输入进程数量:"; cin>>n; cout<<"输入最大请求矩阵 "<<n<<"X"<<m<<endl; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { cin>>max[i][j]; } } cout<<"输入分配矩阵 "<<n<<"X"<<m<<endl; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { cin>>allocation[i][j]; } } for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { need[i][j]=max[i][j]-allocation[i][j]; if (need[i][j] < 0) { return false; } } } cout<<"输入可利用资源向量 "<<1<<"X"<<m<<endl; for (i = 0; i < m; i++) { cin>>available[i]; if (available[i] < 0) { return false; } } return true; } bool bank::IsSafe() { int i,j,k,result ,work[M],finish ; for (i = 0; i < m; i++) { work[i]=available[i]; } for (i = 0; i < n; i++) //标识变量初始化 { finish[i]=false; } for (i = 0, k = 0; i < n; i++) { if (!finish[i]) { for (j = 0; j < m; j++) { if (need[i][j] > work[j]) //目前无法满足该进程 { break; } } if (j == m) //可以满足该进程 { result[k++]=i; for (j = 0; j < m; j++) //将现有可用资源数加上第i进程已经分配了的 { work[j]+=allocation[i][j]; } finish[i]=true; i=-1; //从头扫描 } } } for (i = 0; i < n; i++) { if (!finish[i]) { cout<<"没有安全序列"<<endl; return false; } } cout<<"安全序列是"<<endl; for (i = 0; i < n; i++) { for ( j = 0; j < m; j++) //如果进程已经执行完毕,则安全序列中不再输出 { if (need[result[i]][j] != 0) { break; } } if (j == m) { continue; } cout<<result[i]<<" "; } cout<<endl; return true; } bool bank::Resoure_allocate() { int i,process_id,source_id,amount; cout<<"输入运行进程号:"; cin>>process_id; cout<<"请求资源号:"; cin>>source_id; cout<<"请求数量:"; cin>>amount; if (amount > need[process_id][source_id]) { cout<<"请求不合法,终止运行"<<endl; return false; } if (amount > available[source_id]) { cout<<"请求无法满足,等待"<<endl; return false; } available[source_id]-=amount; //假定分配资源 allocation[process_id][source_id]+=amount; need[process_id][source_id]-=amount; if (!IsSafe()) //检查系统是否安全 { available[source_id]+=amount; allocation[process_id][source_id]-=amount; need[process_id][source_id]+=amount; cout<<"系统不安全,等待"<<endl; return false; } for ( i = 0; i < m; i++) //查看进程是否执行完毕 { if (allocation[process_id][i] != max[process_id][i]) { break; } } if (i == m) //进程执行完毕 { for ( i = 0; i < m; i++) { available[i]+=allocation[process_id][i]; allocation[process_id][i]=0; need[process_id][i]=0; } cout<<"进程"<<process_id<<"运行完毕"<<endl; } return true; } bool bank::IsFinish() { int i,j,finish ; for ( i = 0; i < n; i++) { finish[i]=false; } for ( i = 0; i < n; i++) { for ( j = 0; j < m; j++) { if (need[i][j] != 0) { break; } } if (j == m) { finish[i]=true; } } for ( i = 0; i < n; i++) { if (finish[i] == false) { break; } } if (i != n) { return false; } return true; }
本文出自 “天才鸟蛋” 博客,请务必保留此出处http://curley.blog.51cto.com/1627940/803342
相关文章推荐
- 用银行家算法实现系统资源分配
- c/c++多线程模拟系统资源分配(并通过银行家算法避免死锁产生)
- 银行家算法的实现,有关进程资源分配的算法
- LINUX系统服务器上搭建DHCP服务,实现两大基本功能:1,自动分配ip;2,手工指定ip
- 一个简单的本地化资源管理系统--具体实现
- C++ 动态分配资源的自动释放 – auto_ptr的实现原理
- Java学习笔记之实现Runnable接口可以资源共享(卖票系统)
- 资源分配之银行家算法(含随机调度算法C++代码,此银行家算法,没考虑死锁的发生)
- 再谈权限管理系统问题(权限策略与资源问题:想实现要权限实时申效)
- 时光煮雨 Unity3D实现2D人物动画② Unity2D 动画系统&资源效率
- 网络教学资源平台设计与实现--公告发布系统序列图
- Atitit 三种并发编程模型 艾龙 attilax总结 1. 并发系统可以使用不同的并发模型去实现。 1 2. 并行工作者 并行工作者模型。进来的任务分配给不同的工作者 银行模式 2 2.1.
- 进程退出后,malloc分配的资源会被系统回收
- 利用内核cgroup机制轻松实现类似docker的系统资源管控
- java如何实现在系统资源管理器中选中指定文件/文件夹?
- [系统集成] 基于Kubernetes 部署 jenkins 并动态分配资源
- Shell脚本实现Linux系统和进程资源监控
- 网络教学资源平台设计与实现--公告发布系统E-R图
- 一个资源管理系统的设计--解析linux的cgroup实现
- 利用资源文件实现多语言的系统