银行家算法的实现
A. 银行家算法的算法实现
在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],则转(3);否则,等待。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。 (1)设置两个工作向量Work=AVAILABLE;FINISH
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+ALLOCATION;
Finish=true;
GOTO 2
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。
银行家算法流程图
算法(C语言实现) #include<STRING.H>#include<stdio.h>#include<stdlib.h>#include<CONIO.H>/*用到了getch()*/#defineM5/*进程数*/#defineN3/*资源数*/#defineFALSE0#defineTRUE1/*M个进程对N类资源最大资源需求量*/intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};/*系统可用资源数*/intAVAILABLE[N]={10,5,7};/*M个进程已分配到的N类数量*/intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};/*M个进程已经得到N类资源的资源量*/intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};/*M个进程还需要N类资源的资源量*/intRequest[N]={0,0,0};voidmain(){inti=0,j=0;charflag;voidshowdata();voidchangdata(int);voidrstordata(int);intchkerr();showdata();enter:{printf(请输入需申请资源的进程号(从0到);printf(%d,M-1);printf():);scanf(%d,&i);}if(i<0||i>=M){printf(输入的进程号不存在,重新输入!
);gotoenter;}err:{printf(请输入进程);printf(%d,i);printf(申请的资源数
);printf(类别:ABC
);printf();for(j=0;j<N;j++){scanf(%d,&Request[j]);if(Request[j]>NEED[i][j]){printf(%d,i);printf(号进程);printf(申请的资源数>进程);printf(%d,i);printf(还需要);printf(%d,j);printf(类资源的资源量!申请不合理,出错!请重新选择!
);gotoerr;}else{if(Request[j]>AVAILABLE[j]){printf(进程);printf(%d,i);printf(申请的资源数大于系统可用);printf(%d,j);printf(类资源的资源量!申请不合理,出错!请重新选择!
);gotoerr;}}}}changdata(i);if(chkerr()){rstordata(i);showdata();}elseshowdata();printf(
);printf(按'y'或'Y'键继续,否则退出
);flag=getch();if(flag=='y'||flag=='Y'){gotoenter;}else{exit(0);}}/*显示数组*/voidshowdata(){inti,j;printf(系统可用资源向量:
);printf(***Available***
);printf(资源类别:ABC
);printf(资源数目:);for(j=0;j<N;j++){printf(%d,AVAILABLE[j]);}printf(
);printf(
);printf(各进程还需要的资源量:
);printf(******Need******
);printf(资源类别:ABC
);for(i=0;i<M;i++){printf();printf(%d,i);printf(号进程:);for(j=0;j<N;j++){printf(%d,NEED[i][j]);}printf(
);}printf(
);printf(各进程已经得到的资源量:
);printf(***Allocation***
);printf(资源类别:ABC
);for(i=0;i<M;i++){printf();printf(%d,i);printf(号进程:);/*printf(:
);*/for(j=0;j<N;j++){printf(%d,ALLOCATION[i][j]);}printf(
);}printf(
);}/*系统对进程请求响应,资源向量改变*/voidchangdata(intk){intj;for(j=0;j<N;j++){AVAILABLE[j]=AVAILABLE[j]-Request[j];ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];NEED[k][j]=NEED[k][j]-Request[j];}}/*资源向量改变*/voidrstordata(intk){intj;for(j=0;j<N;j++){AVAILABLE[j]=AVAILABLE[j]+Request[j];ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];NEED[k][j]=NEED[k][j]+Request[j];}}/*安全性检查函数*/intchkerr()//在假定分配资源的情况下检查系统的安全性{intWORK[N],FINISH[M],temp[M];//temp[]用来记录进程安全执行的顺序inti,j,m,k=0,count;for(i=0;i<M;i++)FINISH[i]=FALSE;for(j=0;j<N;j++)WORK[j]=AVAILABLE[j];//把可利用资源数赋给WORK[]for(i=0;i<M;i++){count=0;for(j=0;j<N;j++)if(FINISH[i]==FALSE&&NEED[i][j]<=WORK[j])count++;if(count==N)//当进程各类资源都满足NEED<=WORK时{for(m=0;m<N;m++)WORK[m]=WORK[m]+ALLOCATION[i][m];FINISH[i]=TRUE;temp[k]=i;//记录下满足条件的进程k++;i=-1;}}for(i=0;i<M;i++)if(FINISH[i]==FALSE){printf(系统不安全!!!本次资源申请不成功!!!
);return1;}printf(
);printf(经安全性检查,系统安全,本次分配成功。
);printf(
);printf(本次安全序列:);for(i=0;i<M;i++)//打印安全系统的进程调用顺序{printf(进程);printf(%d,temp[i]);if(i<M-1)printf(->);}printf(
);return0;}
B. C编程完成银行家算法的进程调度及同步模拟的实现
#include<stdio.h>
voidrukou(intjinchenggeshu,intziyuangeshu)
{
inti,j,k=0;
intzanyong[100][100];
intxuqiuzuida[100][100];
intxuyaoziyuangeshu[100][100];
intmeizhongziyuangeshu[100];
intmeizhongzuyuanshengyugeshu[100];
intjieguo[100];
intshifouanquan=0;
intkongshu;
intgaibianshuju;
intyongyouziyuanjishu;
for(i=0;i<jinchenggeshu;i++)
for(j=0;j<ziyuangeshu;j++)
{
printf(" 请输入第%d进程现在占用第%d种资源的个数:",i+1,j+1);
scanf("%d",&zanyong[i][j]);
}
for(i=0;i<jinchenggeshu;i++)
for(j=0;j<ziyuangeshu;j++)
{
printf(" 请输入第%d进程现在所需最大第%d种资源的个数:",i+1,j+1);
scanf("%d",&xuqiuzuida[i][j]);
}
for(i=0;i<ziyuangeshu;i++)
{
printf(" 请输入第%d种资源的个数:",i+1);
scanf("%d",&meizhongziyuangeshu[i]);
}
printf("如果有输入错误想改变 ");
gaibian:printf("想改变占用的数据请输入1 ");
printf("想改变最大资源需求量的数据请输入2 ");
printf("想改变资源中的数据请输入3 ");
printf("退出改变数据请输入4 ");
scanf("%d",&gaibianshuju);
if(gaibianshuju==1)
{
printf("请输入改变哪个进程中的数据:");
scanf("%d",&i);
printf("请输入改变哪种资源中的数据:");
scanf("%d",&j);
printf("请输入新数据:");
scanf("%d",&zanyong[i][j]);
gotogaibian;
}
elseif(gaibianshuju==2)
{
printf("请输入改变哪个进程中的数据:");
scanf("%d",&i);
printf("请输入改变哪种资源中的数据:");
scanf("%d",&j);
printf("请输入新数据:");
scanf("%d",&xuyaoziyuangeshu[i][j]);
gotogaibian;
}
elseif(gaibianshuju==3)
{
printf("请输入改变哪种资源中的数据:");
scanf("%d",&j);
printf("请输入新数据:");
scanf("%d",&meizhongziyuangeshu[j]);
gotogaibian;
}
elseif(gaibianshuju==4);
else{
printf("您选择的无效,请从新选择 :");
gotogaibian;
}
for(i=0;i<jinchenggeshu;i++)
for(j=0;j<ziyuangeshu;j++)
xuyaoziyuangeshu[i][j]=xuqiuzuida[i][j]-zanyong[i][j];
for(j=0;j<ziyuangeshu;j++)
{
yongyouziyuanjishu=0;
for(i=0;i<jinchenggeshu;i++)
yongyouziyuanjishu+=zanyong[i][j];
meizhongzuyuanshengyugeshu[j]=meizhongziyuangeshu[j]-yongyouziyuanjishu;
}
while(1)
{
shifouanquan++;
for(i=0;i<jinchenggeshu;i++)
{
if(zanyong[i][0]!=-1)
{
kongshu=0;
for(j=0;j<ziyuangeshu;j++)
if(meizhongzuyuanshengyugeshu[j]>=xuyaoziyuangeshu[i][j])
kongshu+=1;
if(kongshu==ziyuangeshu)
{
for(j=0;j<ziyuangeshu;j++)
meizhongzuyuanshengyugeshu[j]+=zanyong[i][j];
zanyong[i][0]=-1;
jieguo[k]=i+1;
k++;
}
}
}
if(k==jinchenggeshu)
{
printf("T0时刻是安全状态,安全序列为:");
for(i=0;i<jinchenggeshu;i++)
printf("%d",jieguo[i]);
break;
}
if(shifouanquan>k)
{
printf("T0时刻是不安全状态!");
break;
}
}
}
intmain()
{
intjinchenggeshu,ziyuangeshu;
printf("请输入进程个数:");
scanf("%d",&jinchenggeshu);
printf("请输入资源种类数:");
scanf("%d",&ziyuangeshu);
rukou(jinchenggeshu,ziyuangeshu);
return0;
}
C. 求java语言的银行家算法
银行家算法
一.程序说明:
本算法有3个进程,3类资源。初始可用资源向量为Available{10,8,7},然后设置各进程的最大需求矩阵MAX以及分配矩阵Alloction,由此算出需求矩阵Need。然后判断当前系统资源分配是否处于安全状态,否则结束进程。最后,在当前分配资源后的系统安全时,选择一进程,并请求各类所需资源矩阵Request,尝试分配并修改资源分配状况,判断此进程请求是否该分配,进而进入安全算法判断是否能形成一个安全序列,如果有则分配,否则不分配。
二.程序代码:
算法类:
package bankerclass;
import java.util.Scanner;
public class BankerClass {
int[] Available = {10, 8, 7};
int[][] Max = new int[3][3];
int[][] Alloction = new int[3][3];
int[][] Need = new int[3][3];
int[][] Request = new int[3][3];
int[] Work = new int[3];
int num = 0;//进程编号
Scanner in = new Scanner(System.in);
public BankerClass() {
// Max={{6,3,2},{5,6,1},{2,3,2}};
}
public void setSystemVariable(){//设置各初始系统变量,并判断是否处于安全状态。
setMax();
setAlloction();
printSystemVariable();
SecurityAlgorithm();
}
public void setMax() {//设置Max矩阵
System.out.println("请设置各进程的最大需求矩阵Max:");
for (int i = 0; i < 3; i++) {
System.out.println("请输入进程P" + i + "的最大资源需求量:");
for (int j = 0; j < 3; j++) {
Max[i][j] = in.nextInt();
}
}
}
public void setAlloction() {//设置已分配矩阵Alloction
System.out.println("请设置请各进程分配矩阵Alloction:");
for (int i = 0; i < 3; i++) {
System.out.println("晴输入进程P" + i + "的分配资源量:");
for (int j = 0; j < 3; j++) {
Alloction[i][j] = in.nextInt();
}
}
System.out.println("Available=Available-Alloction.");
System.out.println("Need=Max-Alloction.");
for (int i = 0; i < 3; i++) {//设置Alloction矩阵
for (int j = 0; j < 3; j++) {
Available[i] = Available[i] - Alloction[j][i];
}
}
for (int i = 0; i < 3; i++) {//设置Need矩阵
for (int j = 0; j < 3; j++) {
Need[i][j] = Max[i][j] - Alloction[i][j];
}
}
}
public void printSystemVariable(){
System.out.println("此时资源分配量如下:");
System.out.println("进程 "+" Max "+" Alloction "+" Need "+" Available ");
for(int i=0;i<3;i++){
System.out.print("P"+i+" ");
for(int j=0;j<3;j++){
System.out.print(Max[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<3;j++){
System.out.print(Alloction[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<3;j++){
System.out.print(Need[i][j]+" ");
}
System.out.print("| ");
if(i==0){
for(int j=0;j<3;j++){
System.out.print(Available[j]+" ");
}
}
System.out.println();
}
}
public void setRequest() {//设置请求资源量Request
System.out.println("请输入请求资源的进程编号:");
num= in.nextInt();//设置全局变量进程编号num
System.out.println("请输入请求各资源的数量:");
for (int j = 0; j < 3; j++) {
Request[num][j] = in.nextInt();
}
System.out.println("即进程P" + num + "对各资源请求Request:(" + Request[num][0] + "," + Request[num][1] + "," + Request[num][2] + ").");
BankerAlgorithm();
}
public void BankerAlgorithm() {//银行家算法
boolean T=true;
if (Request[num][0] <= Need[num][0] && Request[num][1] <= Need[num][1] && Request[num][2] <= Need[num][2]) {//判断Request是否小于Need
if (Request[num][0] <= Available[0] && Request[num][1] <= Available[1] && Request[num][2] <= Available[2]) {//判断Request是否小于Alloction
for (int i = 0; i < 3; i++) {
Available[i] -= Request[num][i];
Alloction[num][i] += Request[num][i];
Need[num][i] -= Request[num][i];
}
} else {
System.out.println("当前没有足够的资源可分配,进程P" + num + "需等待。");
T=false;
}
} else {
System.out.println("进程P" + num + "请求已经超出最大需求量Need.");
T=false;
}
if(T==true){
printSystemVariable();
System.out.println("现在进入安全算法:");
SecurityAlgorithm();
}
}
public void SecurityAlgorithm() {//安全算法
boolean[] Finish = {false, false, false};//初始化Finish
int count = 0;//完成进程数
int circle=0;//循环圈数
int[] S=new int[3];//安全序列
for (int i = 0; i < 3; i++) {//设置工作向量
Work[i] = Available[i];
}
System.out.println("进程 "+" Work "+" Alloction "+" Need "+"Work+Available ");
while (count < 3) {
for (int i = 0; i < 3; i++) {
if (Finish[i]==false&&Need[i][0]<=Work[0]&&Need[i][1]<=Work[1]&&Need[i][2]<=Work[2]) {//判断条件
System.out.print("P"+i+" ");
for (int k = 0; k < 3; k++){
System.out.print(Work[k]+" ");
}
System.out.print("| ");
for (int j = 0; j<3;j++){
Work[j]+=Alloction[i][j];
}
Finish[i]=true;//当当前进程能满足时
S[count]=i;//设置当前序列排号
count++;//满足进程数加1
for(int j=0;j<3;j++){
System.out.print(Alloction[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<3;j++){
System.out.print(Need[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<3;j++){
System.out.print(Work[j]+" ");
}
System.out.println();
}
}
circle++;//循环圈数加1
if(count==3){//判断是否满足所有进程需要
System.out.print("此时存在一个安全序列:");
for (int i = 0; i<3;i++){//输出安全序列
System.out.print("P"+S[i]+" ");
}
System.out.println("故当前可分配!");
break;//跳出循环
}
if(count<circle){//判断完成进程数是否小于循环圈数
count=5;
System.out.println("当前系统处于不安全状态,故不存在安全序列。");
break;//跳出循环
}
}
}
}
主类:
package bankerclass;
import java.util.Scanner;
public class TestBankerClass {
public static void main(String[] args) {
// TODO code application logic here
boolean Choose = true;
String C;
Scanner in = new Scanner(System.in);
BankerClass T = new BankerClass();
System.out.println("这是一个三个进程,初始系统可用三类资源为{10,8,7}的银行家算法:");
T.setSystemVariable();
while (Choose == true) {
T.setRequest();
System.out.println("您是否还要进行请求:y/n?");
C = in.nextLine();
if (C.endsWith("n")) {
Choose = false;
}
}
}
}
三.随机运行过程
1.
run:
这是一个三个进程,初始系统可用三类资源为{10,8,7}的银行家算法:
请设置各进程的最大需求矩阵Max:
请输入进程P0的最大资源需求量:
8 7 5
请输入进程P1的最大资源需求量:
5 2 5
请输入进程P2的最大资源需求量:
6 6 2
请设置请各进程分配矩阵Alloction:
晴输入进程P0的分配资源量:
3 2 0
晴输入进程P1的分配资源量:
2 0 2
晴输入进程P2的分配资源量:
1 3 2
Available=Available-Alloction.
Need=Max-Alloction.
此时资源分配量如下:
进程 Max Alloction Need Available
P0 8 7 5 | 3 2 0 | 5 5 5 | 4 3 3
P1 5 2 5 | 2 0 2 | 3 2 3 |
P2 6 6 2 | 1 3 2 | 5 3 0 |
进程 Work Alloction Need Work+Available
P1 4 3 3 | 2 0 2 | 3 2 3 | 6 3 5
P2 6 3 5 | 1 3 2 | 5 3 0 | 7 6 7
P0 7 6 7 | 3 2 0 | 5 5 5 | 10 8 7
此时存在一个安全序列:P1 P2 P0 故当前可分配!
请输入请求资源的进程编号:
0
请输入请求各资源的数量:
1 0 0
即进程P0对各资源请求Request:(1,0,0).
此时资源分配量如下:
进程 Max Alloction Need Available
P0 8 7 5 | 4 2 0 | 4 5 5 | 3 3 3
P1 5 2 5 | 2 0 2 | 3 2 3 |
P2 6 6 2 | 1 3 2 | 5 3 0 |
现在进入安全算法:
进程 Work Alloction Need Work+Available
P1 3 3 3 | 2 0 2 | 3 2 3 | 5 3 5
P2 5 3 5 | 1 3 2 | 5 3 0 | 6 6 7
P0 6 6 7 | 4 2 0 | 4 5 5 | 10 8 7
此时存在一个安全序列:P1 P2 P0 故当前可分配!
您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
2
请输入请求各资源的数量:
0 1 0
即进程P2对各资源请求Request:(0,1,0).
此时资源分配量如下:
进程 Max Alloction Need Available
P0 8 7 5 | 4 2 0 | 4 5 5 | 3 2 3
P1 5 2 5 | 2 0 2 | 3 2 3 |
P2 6 6 2 | 1 4 2 | 5 2 0 |
现在进入安全算法:
进程 Work Alloction Need Work+Available
P1 3 2 3 | 2 0 2 | 3 2 3 | 5 2 5
P2 5 2 5 | 1 4 2 | 5 2 0 | 6 6 7
P0 6 6 7 | 4 2 0 | 4 5 5 | 10 8 7
此时存在一个安全序列:P1 P2 P0 故当前可分配!
您是否还要进行请求:y/n?
n
成功生成(总时间:1 分钟 38 秒)
D. 在C++中,编写的银行家算法中有以下的语句,麻烦帮忙解释这3个语句,并用java实现,怎么实现,谢谢先!!
在某时刻系统中所有进程可以排列一个安全序列:,刚称此时,系统是安全的.
所谓安全序列是指对于P2,都有它所需要剩余资源数量不大于系统掌握的剩余的空间资源与所有Pi(j<i)所占的资源之和.
2.不安全状态可能产生死锁.
目前状态 最大需求 尚需
P1 3 9 6
P2 5 10 5
P3 2 4 2
在每一次进程中申请的资源,判定一下,若实际分配的话,之后系统是否安全.
3.银行家算法的思路:
1),进程一开始向系统提出最大需求量.
2),进程每次提出新的需求(分期贷款)都统计是否超出它事先提出的最大需求量.
3),若正常,则判断该进程所需剩余剩余量(包括本次申请)是否超出系统所掌握的
剩余资源量,若不超出,则分配,否则等待.
4.银行家算法的数据结构.
1),系统剩余资源量A[n],其中A[n]表示第I类资源剩余量.
2),各进程最大需求量,B[m][n],其中B[j][i]表示进程j对i
类资源最大需求.
3),已分配资源量C[m][n],其中C[j][i]表示系统j程已得到的第i资源的数量.
4),剩余需求量.D[m][n],其中D[j][i]对第i资源尚需的数目.
5.银行家算法流程:当某时刻,某进程时,提出新的资源申请,系统作以下操作:
1),判定E[n]是否大于D[j][n],若大于,表示出错.
2),判定E[n]是否大于系统剩余量A[n],若大于,则该进程等待.
3),若以上两步没有问题,尝试分配,即各变量作调整.
4),按照安全性推测算法,判断,分配过后,系统是否安全,若安全,则实际分配,否则,撤消分配,让进程等待.
6."安全性检测"算法
1),先定义两个变量,用来表示推算过程的数据.
F[n]=A[n],表示推算过程中,系统中剩余资源量的变化.
J[n]=False表示推算过程中各进程是否假设"已完成"
2),流程:
在"剩余"的进程中(在推算)过程中,一些进程假设已完成,查找D[j][n]<=F[n]的进程,找到后令J[j]=True
(假设该进程完成),F[n]+D[j][n](该进程所占资源释放),如此循环执行.
若最后,所有的F[n]=True(在推算过程中,所有进程均可以完成),则表示(分配过后)系统是安全的,否则系统是不安全的.
#include "malloc.h"
#include "stdio.h"
#define alloclen sizeof(struct allocation)
#define maxlen sizeof(struct max)
#define avalen sizeof(struct available)
#define needlen sizeof(struct need)
#define finilen sizeof(struct finish)
#define pathlen sizeof(struct path)
struct allocation
{
int value;
struct allocation *next;
};
struct max
{
int value;
struct max *next;
};
struct available
{
int value;
struct available *next;
};
struct need
{
int value;
struct need *next;
};
struct path
{
int value;
struct path *next;
};
struct finish
{
int stat;
struct finish *next;
};
int main()
{
int row,colum,status=0,i,j,t,temp,processtest;
struct allocation *allochead,*alloc1,*alloc2,*alloctemp;
struct max *maxhead,*maxium1,*maxium2,*maxtemp;
struct available *avahead,*available1,*available2,*availabletemp,*workhead,*work1,*work2,*worktemp,*worktemp1;
struct need *needhead,*need1,*need2,*needtemp;
struct finish *finihead,*finish1,*finish2,*finishtemp;
struct path *pathhead,*path1,*path2,*pathtemp;
char c;
printf("\nPlease enter the type of sources the system has:\n");
scanf("%d",&colum);
printf("Please enter the number of processes now in the memory:\n");
scanf("%d",&row);
printf("Please enter the allocation array:\n");
for(i=0;i<row;i++)
{
printf("The allocation for process p%d:\n",i);
for (j=0;j<colum;j++)
{
printf("The type %c system resource allocated:\n",'A'+j);
if(status==0)
{
allochead=alloc1=alloc2=(struct allocation*)malloc(alloclen);
alloc1->next=alloc2->next=NULL;
scanf("%d",&allochead->value);
status++;
}
else
{
alloc2=(struct allocation *)malloc(alloclen);
scanf("%d,%d",&alloc2->value);
if(status==1)
{
allochead->next=alloc2;
status++;
}
alloc1->next=alloc2;
alloc1=alloc2;
}
}
}
alloc2->next=NULL;
status=0;
printf("Please enter the max array:\n");
for(i=0;i<row;i++)
{
printf("The max needed from process p%d:\n",i);
for (j=0;j<colum;j++)
{
printf("The type %c maxium system resource may needed:\n",'A'+j);
if(status==0)
{
maxhead=maxium1=maxium2=(struct max*)malloc(maxlen);
maxium1->next=maxium2->next=NULL;
scanf("%d",&maxium1->value);
status++;
}
else
{
maxium2=(struct max *)malloc(maxlen);
scanf("%d,%d",&maxium2->value);
if(status==1)
{
maxhead->next=maxium2;
status++;
}
maxium1->next=maxium2;
maxium1=maxium2;
}
}
}
maxium2->next=NULL;
status=0;
printf("Please enter the available array now exists in the system:\n");
for (j=0;j<colum;j++)
{
printf("The type %c available system resource number:\n",'A'+j);
if(status==0)
{
avahead=available1=available2=(struct available*)malloc(avalen);
workhead=work1=work2=(struct available*)malloc(avalen);
available1->next=available2->next=NULL;
work1->next=work2->next=NULL;
scanf("%d",&available1->value);
work1->value=available1->value;
status++;
}
else
{
available2=(struct available*)malloc(avalen);
work2=(struct available*)malloc(avalen);
scanf("%d,%d",&available2->value);
work2->value=available2->value;
if(status==1)
{
avahead->next=available2;
workhead->next=work2;
status++;
}
available1->next=available2;
available1=available2;
work1->next=work2;
work1=work2;
}
}
available2->next=NULL;
work2->next=NULL;
status=0;
alloctemp=allochead;
maxtemp=maxhead;
for(i=0;i<row;i++)
for (j=0;j<colum;j++)
{
if(status==0)
{
needhead=need1=need2=(struct need*)malloc(needlen);
need1->next=need2->next=NULL;
need1->value=maxtemp->value-alloctemp->value;
status++;
}
else
{
need2=(struct need *)malloc(needlen);
need2->value=(maxtemp->value)-(alloctemp->value);
if(status==1)
{
needhead->next=need2;
status++;
}
need1->next=need2;
need1=need2;
}
maxtemp=maxtemp->next;
alloctemp=alloctemp->next;
}
need2->next=NULL;
status=0;
for(i=0;i<row;i++)
{
if(status==0)
{
finihead=finish1=finish2=(struct finish*)malloc(finilen);
finish1->next=finish2->next=NULL;
finish1->stat=0;
status++;
}
else
{
finish2=(struct finish*)malloc(finilen);
finish2->stat=0;
if(status==1)
{
finihead->next=finish2;
status++;
}
finish1->next=finish2;
finish1=finish2;
}
}
finish2->next=NULL; /*Initialization compleated*/
status=0;
processtest=0;
for(temp=0;temp<row;temp++)
{
alloctemp=allochead;
needtemp=needhead;
finishtemp=finihead;
worktemp=workhead;
for(i=0;i<row;i++)
{
worktemp1=worktemp;
if(finishtemp->stat==0)
{
for(j=0;j<colum;j++,needtemp=needtemp->next,worktemp=worktemp->next)
if(needtemp->value<=worktemp->value)
processtest++;
if(processtest==colum)
{
for(j=0;j<colum;j++)
{
worktemp1->value+=alloctemp->value;
worktemp1=worktemp1->next;
alloctemp=alloctemp->next;
}
if(status==0)
{
pathhead=path1=path2=(struct path*)malloc(pathlen);
path1->next=path2->next=NULL;
path1->value=i;
status++;
}
else
{
path2=(struct path*)malloc(pathlen);
path2->value=i;
if(status==1)
{
pathhead->next=path2;
status++;
}
path1->next=path2;
path1=path2;
}
finishtemp->stat=1;
}
else
{
for(t=0;t<colum;t++)
alloctemp=alloctemp->next;
finishtemp->stat=0;
}
}
else
for(t=0;t<colum;t++)
{
needtemp=needtemp->next;
alloctemp=alloctemp->next;
}
processtest=0;
worktemp=workhead;
finishtemp=finishtemp->next;
}
}
path2->next=NULL;
finishtemp=finihead;
for(temp=0;temp<row;temp++)
{
if(finishtemp->value==0)
{
printf("\nWARNING,the system is in nonsafe status!\n");
exit(0);
}
finishtemp=finishtemp->next;
}
printf("\nThe system is in safe status!\n");
printf("\nThe safe sequence is: \n");
do
{
printf("p%d ",pathhead->value);
}
while(pathhead=pathhead->next);
}
E. 浅析银行家算法
作为避免死锁的一种算法,银行家算法可以说是最为出名的了。这个名字的来源是因为该算法起初是为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。在操作系统中也可以用它来实现避免死锁。
首先我们要了解银行家算法的本质也即避免死锁的原理。避免死锁作为一种事先预防死锁的策略,原理是在为各个进程分配资源的过程中不允许系统进去不安全状态,以此来避免死锁的发生。所谓安全状态,是指系统能按某种进程推进顺序为每个进程分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺利地完成。此时称该进程推进序列为安全序列,如果无法找到这样一个安全序列,则称系统处于不安全状态。
银行家算法中的数据结构。为了实现银行家算法,在系统中必须设置这样四个数据结构,分别用来描述系统中可利用的资源,所有进程对资源的最大需求,系统中的资源分配以及所有进程还需要多少资源的情况。
(1)可利用资源向量Available。这是一个含有m个元表的数组,其中的每一个元素代表一类可利用的资源数目。其数值随该类资源的分配和回收而动态地改变。如果 Available=K,则表示系统中现有Rj类资源K个。
(2)最大需求矩阵Max。这是一个nxm的矩阵,它定义了系统中n个进程中的每个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
(3)分配矩阵 Allocation。这也是一个nxm的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,表示进程i当前已分得Rj类资源的数目为K。
(4)需求矩阵Need。这也是一个nxm的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个才能完成。
当一个进程发出请求资源的请求后,如果它所请求的资源大于目前系统可利用资源则不予分配。如果小于可利用资源,则系统试探着把资源分配给该进程,并修改分配之后的资源数值。接着系统执行安全算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给该进程,以完成本次分配。否则,将本次的试探分配作废,恢复原来的资源分配状态,让该进程等待。
F. 银行家算法的实现,安全性算法中 这条语句是什么意思Work[j]∶=Work[i]+Allocation[i,j];
work[j]表示当前系统可用的第j类资源,Allocation[i][j]表示当前已经分配给进程i使用的第j类资源数量。
Work[j]= Work[j]+ Allocation[i][j]
这句的意思是目前进程已经利用手上资源完成相关工作了,这些已分配的资源可以重新归还系统了,所以系统可用的第j类资源work[j]就增加了,增加量就是当前进程想要归还的资源量Allocation[i][j]
如有疑惑欢迎追问!
G. 银行家算法
什么是银行家算法:
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全序列是指一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。
安全状态
如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。
不安全状态
不存在一个安全序列。不安全状态不一定导致死锁。
原理:
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2) 顾客可以分歧贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
程序举例:
已知进程{P0,P1,P2,P3,P4},有三类系统资源A、B、C的数量分别为10、5、7,在T0时刻的资源
(1)若进程P1请求资源,发出请求向量Request1(1,0,2),编写程序用银行家算法判断系统能否将资源分配给它;
(2)若进程P2提出请求Request(0,1,0),用银行家算法程序验证系统能否将资源分配给它。
程序代码:
P1进程提出的请求,可以分配。
P2进程不能分配,因为请求的B类资源超过了它的最大值。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 50
void main()
{
unsigned int Available[MAXSIZE]; //可利用资源向量
unsigned int Max[MAXSIZE][MAXSIZE]; //最大需求矩阵
unsigned int Allocation[MAXSIZE][MAXSIZE]; //已分配矩阵
unsigned int Need[MAXSIZE][MAXSIZE]; //需求矩阵
unsigned int Request[MAXSIZE]; //请求向量
unsigned int Work[MAXSIZE]; //工作向量
bool Finish[MAXSIZE]; //是否有足够资源分配给进程,使之运行完成
unsigned int SafeSequence[MAXSIZE]; //安全序列
int i,j;
int p; //请求资源的进程的下标
int temp = 0; //安全序列下标
int total = 0;
int N;
int M;
printf("请输入进程数N=");
scanf("%d",&N);
printf("请输入资源种类数M=");
scanf("%d",&M);
//用户输入数据,初始化Available数组
printf("初始化可用资源数组:\n");
for(i=0; i<M; i++)
{
printf("\t%c类资源:",65+i);
scanf("%d",&Available[i]);
}
//用户输入数据,初始化Max数组
printf("初始化最大需求数组:\n");
for(i=0; i<N; i++)
{
printf("\tP%d进程最大需要\n",i);
for(j=0; j<M; j++)
{
printf("\t\t%c类资源:",65+j);
scanf("%d",&Max[i][j]);
}
}
//用户输入数据,初始化Allocation数组
printf("初始化已分配资源数组:\n");
for(i=0; i<N; i++)
{
printf("\tP%d进程已分配\n",i);
for(j=0; j<M; j++)
{
printf("\t\t%c类资源:",65+j);
scanf("%d",&Allocation[i][j]);
}
}
//初始化Need数组
for(i=0; i<N; i++)
for(j=0; j<M; j++)
{
Need[i][j] = Max[i][j] - Allocation[i][j];
}
//进程发出资源请求后检查
do
{
printf("资源请求:\n");
printf("\t输入请求资源的进程下标:");
scanf("%d",&p);
printf("\t进程P%d请求\n",p);
//初始化请求向量
for(i=0; i<M; i++)
{
printf("\t\t%c类资源:",65+i);
scanf("%d",&Request[i]);
}
for(i=0; i<M; i++) //检查Request <= Need ?
if(Request[i] > Need[p][i])
{
printf("\t请求的%c类资源数超过它所宣布的最大值!\n",65+i);
break;
}
if(i == M) //通过上层检查,继续检查Request <= Available ?
{
for(i=0; i<M; i++)
if(Request[i] > Available[i])
{
printf("\t尚无足够%c类资源,P%d须等待!\n",65+i,p);
break;
}
}
if(i == M) //尝试分配
{
for(i=0; i<M; i++)
{
Available[i] -= Request[i];
Allocation[p][i] += Request[i];
Need[p][i] -= Request[i];
}
}
}while(i<M);
//初始化Work,Finish向量
for(i=0; i<M; i++)
{
Work[i] = Available[i];
}
for(i=0; i<N; i++)
{
Finish[i] = false;
}
//安全性算法
do
{
total = temp;
for(i=0; i<N; i++)
{
if(Finish[i] == false)
{
for(j=0; j<M; j++)
if(Need[i][j] > Work[j])
{
break;
}
if(j == M) //各类资源都满足Need <= Work
{
for(j=0; j<M; j++)
{
Work[j] += Allocation[i][j]; //释放资源
}
Finish[i] = true;
SafeSequence[temp++] = i; //加入安全序列
}
}
}
}while(total != temp); //所有进程检查一遍之后,如果安全序列有变化,则进行下一轮
//否则说明所有的Finish都为true,或者因没有安全序列退出循环
if(temp == N)
{
printf("安全序列:");
for(temp=0; temp<N; temp++)
{
printf("P%d ",SafeSequence[temp]);
}
}
else
{
printf("系统处于不安全状态!不能分配!\n");
}
getchar();
getchar();
}
这个程序还行,输入有点麻烦,我自己编写的是用文件输入系统描述信息的,但是缺少说明,怕你搞不明白。希望对你有所帮助!
H. Java语言期末课程设计“操作系统中银行家算法的实现”
有电子版可以参考。
I. 编程实现银行家算法,最好可以告诉我方法,非常感谢。
#include<stdio.h>
#define N 4
#define M 5
main()
{
int maxc[M][N]={3,2,1,4,0,2,5,2,5,1,0,5,1,5,3,0,3,0,3,3};
int availc[M][N]={2,0,1,1,0,1,2,1,4,0,0,3,0,2,1,0,1,0,3,0};
int c[N]={8,5,9,7};
int avail[N]={0};
int i=0,j=0,k[M]={-1,-1,-1,-1,-1},kk=0;
int flag=0;
int flag2=0;
/*The max need table*/
printf("nt The max need table");
printf("n process ");
for(i=0;i<N;i++)
{printf("tR[%d]",i);
}
for(i=0;i<M;i++)
{printf("n p[%d]",i);
for(j=0;j<N;j++)
{printf("t%d",maxc[i][j]);
}
}
/*the rest resource*/
for(j=0;j<N;j++)
{
for(i=0;i<M;i++)
{avail[j]+=availc[i][j];}
avail[j]=c[j]-avail[j];
}
/*The alloc table*/
printf("nnt The allocation table");
printf("n process ");
for(i=0;i<N;i++)
{printf("tR[%d]",i);
}
for(i=0;i<M;i++)
{printf("n p[%d]",i);
for(j=0;j<N;j++)
{printf("t%d",availc[i][j]);
}
}
/*the avail table*/
printf("nn avail");
for(j=0;j<N;j++)
{printf("t%d",avail[j]);}
i=0,j=0;
while(i<M)
{
for(j=0;j<M;j++)
{if(k[j]==i)
{flag=1;i++;break;}
}
if(flag==1)
{flag=0;continue;}
for(j=0;j<N;j++)
{if(avail[j]<maxc[i][j]-availc[i][j])
{flag2=1;i++;j=0;break;}
}
if(flag2==1)
{flag2=0;continue;}
k[kk]=i;
for(j=0;j<N;j++)
{avail[j]+=availc[k[kk]][j];}
/*the avail table*/
printf("n after p[%d]",i);
for(j=0;j<N;j++)
{printf("t%d",avail[j]);}
if(kk==M-1)
{printf("nThis is safe!n");
for(j=0;j<M-1;j++)
{printf("Process[%d]-->",k[j]);}
printf("Process[%d]n",k[M-1]);
break;
}
kk++;
i=0;
}
if(i==M)
printf("nthis is no safe alloc!");
getchar();
}
J. 第三章 银行家算法
(1)各类可利用资源的数量
u向量Available:(i1,i2,…,im),含m个元素,每个元素代表一类可利用的资源数目。
u动态变化的,初始值是系统配置的该类资源的全部数目,值随资源的分配与回收而动态的改变。
u实现:一维数组。Available【j】=K,表示系统中Rj类资源现有可用数量为K个。
(2)每个进程对每类资源的需求
最大需求、已获得的、还需要的
v最大需求矩阵Max
vn*m,系统中n个进程中每个进程分别对m类资源的最大需求。
v取值:根据进程需求赋初始值。
v实现:二维数组。Max【i,j】=K,表示进程 i
需要Rj类资源的最大数目为K。
算法过程:
就是对各进程的Request向量及资源数量进行一系列判断及值操作。
进程Pi发出资源请求后,系统按下述步骤进行检查:
首先是两个基本判断:
(1)IF Requesti[j]<= Need[i,j]
THEN转向步骤2;
ELSE认为出错,所需资源数超过宣布的最大值(自我矛盾)
(2)IF Requesti[j]<= Available[j]
THEN转向步骤3;
ELSE表示尚无足够资源,Pi需等待(现实不满足)
如果上面两步判断都通过了,进入实质的资源分析
(3)系统试探着把资源分配给进程Pi
,并修改相应数据结构的值(假设性操作):
Available【j】 =
Allocation【i,j】=
Need【i,j】=
(4)系统执行安全性算法,判断新的资源分配状态是否是安全的。
即:找一个安全序列,使这些进程按顺序执行完)如果能够找到,则将假设操作真正实施完成资源分配。
(1)需要一些记录信息的数据结构,设置两个向量:
v工作向量work
算法开始时work=Available;
系统找安全序列的过程需要不断判断和修改当前资源数量,不能直接修改原始数据记录Aailable。
v标志向量Finish
表示每个进程是否有足够的资源使之运行完成。开始时所以进程都设置初值Finish[i]:=false;
找安全序列的过程相当于使所有Finish[i]:=true。
(2)找安全序列的过程
从Finish[i] = false 的进程集合中找一个进程
IFNeed[i,j] <= work[j]
THEN 执行步骤 a;
ELSE 执行步骤 b;
a)假设Pi获得资源顺利执行完,释放出分配给它的资源,修改相应的值:
work【j】 = work【i】+Allocation【i,j】;
Finish【i】= true;
goto step (2);//返回去继续找下一个进程。
b)当算法不再在(2)、a)步间循环找进程,到达本步时,若所有Finish[i]=true都满足,则表示所有进程都按某个顺序执行完了,系统处于安全状态;否则,系统当前所处的资源分配状态是不安全状态。