题目:
共享资源分配与银行家算法
[问题描述]
本题主要内容是模拟实现资源分配。银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
通过对这个算法的设计,让学生能够对书本知识有更深的理解,在操作和其它方面有更高的提升。
[基本要求]具体用银行家算法实现资源分配。要求如下:
(1)设计一个3个并发进程共享3类不同资源的系统,进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。
(2)设计用银行家算法,实现资源分配,应具有显示或打印各进程依次要求申请的资源数以及依次分配资源的情况。
(3)确定一组各进程依次申请资源数的序列,输出运行结果。
[方案设计及开发过程]
1银行家分配算法,顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行加资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,每个进程都无法继续执行下去的死锁现象。
把个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的资源需求总量不能超过系统拥有的资源总数,银行算法进行资源分配可以避免死锁.
2.算法描述
银行家算法:
设进程I提出请求Request[N],则银行家算法按如下规则进行判断。
(1)如果Request[N]<=NEED[I,N],则转(2);否则,出错。
(2)如果Request[N]<=AVAILABLE,则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE=AVAILABLE-REQUEST
ALLOCATION=ALLOCATION+REQUEST
NEED=NEED-REQUEST
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
3.安全性检查
(1)设置两个工作向量WORK=AVAILABLE;FINISH[M]=FALSE
(2)从进程集合中找到一个满足下述条件的进程,
FINISH[i]=FALSE
NEED<=WORK
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
WORK=WORK+ALLOCATION
FINISH=TRUE
GOTO 2
(4)如所有的进程Finish[M]=true,则表示安全;否则系统不安全。
3.数据结构
假设有M个进程N类资源,则有如下数据结构:
#defineW 10
#defineR 20
intM ; //总进程数
intN ; //资源种类
intALL_RESOURCE[W]; //各种资源的数目总和
intMAX[W][R]; //M个进程对N类资源最大资源需求量
intAVAILABLE[R]; //系统可用资源数
intALLOCATION[W][R]; //M个进程已经得到N类资源的资源量
intNEED[W][R]; //M个进程还需要N类资源的资源量
intRequest[R]; //请求资源个数
#include<stdio.h>
#include<stdlib.h>
#define W 10
#define R 20
int M ; //总的进程数
int N ; // 总的资源总数
int DQ ; //当前进程
int ALL_SOURCE[W] ; //各种资源数目总和
int REQUEST[R]; //请求资源个数
//银行家算法
int MAX[W][R] ; //M 个进程对N 类资源最大资源需求量
int ALLOCATION[W][R]; //M 个进程已经得到N 类资源的资源量
int NEED[W][R]; //M 个进程还需要N类资源的资源量
int AVAILABLE[R] ; //系统可用资源数
//安全性检测
int WORK[R];
int FINISH[W];
//初始化信息进程与资源信息
void init(){
int i , j ;
printf("请输入进程总数:"); scanf("%d",&M);
printf("请输入资源总数:"); scanf("%d",&N);
for( i = 1 ; i <= M ; i++ ){
printf("请输入%d进程的信息:\n",i);
for( j = 1 ; j <= N ; j++ ){
printf("max[%d][%d]=" , i , j ); scanf("%d" , &MAX[i][j] );
printf("allcoation[%d][%d]=" , i , j ); scanf("%d" , &ALLOCATION[i][j] ); NEED[i][j] = MAX[i][j] - ALLOCATION[i][j] ;
}
}
for( j = 1 ; j <= N ; j++){
printf("资源%d的可用资源数目:",j);
scanf("%d",&AVAILABLE[j]);
}
for( i = 1 ; i <= R ; i++){
FINISH[i] = 0 ;
}
//testing
/*
printf("M = %d ", M ); printf("N = %d \n ", N );
for( i = 1 ; i <= M ; i++ ){
for( j = 1 ; j <= N ; j++){
printf("max[%d][%d] = %d ", i , j , MAX[i][j]);
printf("allocation[%d][%d] = %d ", i , j , ALLOCATION[i][j]);
printf("need[%d][%d] = %d ", i ,j , NEED[i][j]);
}
printf("\n");
}
**/
}
//打印进程与资源关系
void Test_Printf(){
int i , j ;
printf("\n");
printf("***************************************************************************\n");
printf("进程总数:M = %d ", M ); printf("资源总数:N = %d\n", N );
for( i = 1 ; i <= M ; i++ ){
printf("进程%d:\n",i);
for( j = 1 ; j <= N ; j++){
printf("max[%d][%d] = %d ", i , j , MAX[i][j]);
printf("allocation[%d][%d] = %d ", i , j , ALLOCATION[i][j]);
printf("need[%d][%d] = %d ", i ,j , NEED[i][j]);
printf("\n");
}
printf("\n");
}
printf("可用资源总数:\n");
for( i = 1 ; i <= N ; i++){
printf("AVAI[%d] = %d ", i ,AVAILABLE[i]);
if(i%5==0)
printf("\n");
}
printf("\n");
printf("***************************************************************************\n");
}
int FIND(){
int i , j , flag = 0 ;
for( i = 1 ; i <= M ; i++){ //进程
for( j = 1 ; j <= N ; j++ ){ //资源
if( ( FINISH[i] == 0) && (NEED[i][j] <= WORK[j] ) ) ;
else
break ;
}
if( j == N+1) {
for(j = 1 ; j <= N ; j++){
WORK[j] = WORK[j] + ALLOCATION[i][j];
ALLOCATION[i][j] = MAX[i][j] ;
NEED[i][j] = 0 ;
FINISH[i] = 1 ;
}
printf("\n");
printf("执行进程:%d\n",i);
printf("work 1-3 : %d %d %d\n",WORK[1],WORK[2],WORK[3]);
/*
*printf("是否显示执行过程(是:1 / 否:0):");
* scanf("%d",&flag);
* if(flag==y) Test_Printf();
*/
return i ;
}
}
if(i==M+1)return 0 ;
}
//安全性检测
int Test_Safe(){
int i , flag , j ;
for( i = 1 ; i <= N ; i++ ){
WORK[i] = AVAILABLE[i] ;
}
for( i = 1 ; i <= M ; i++){
FINISH[i] =0 ;
}
// printf("%d %d %d %d %d \n",FINISH[1], FINISH[2], FINISH[3] , FINISH[4], FINISH[5]);
// printf("DQ: __ %d\n",DQ);
DQ = FIND();
// printf("DQ: __ %d\n",DQ);
while(DQ!=0){
DQ=FIND();
}
return 1 ;
}
//尝试分配
void Try(){
int i , j ;
//初步检测是否能分配
for( i = 1 ; i <= N ; i++){
if(REQUEST[i] <= NEED[DQ][i]) ;
else {
printf("请求资源数目大于宣布资源数目");
break ;
}
if(REQUEST[i]<=AVAILABLE[i] ) ;
else {
printf("该进程需要等待 \n");
}
}
//开始尝试分配
for( i =1 ; i <= N ; i++ ){
AVAILABLE[i]=AVAILABLE[i]-REQUEST[i] ;
ALLOCATION[DQ][i]=ALLOCATION[DQ][i]+REQUEST[i] ;
NEED[DQ][i]=NEED[DQ][i]-REQUEST[i] ;
}
Test_Printf();
Test_Safe();
}
void Ask(){
/********
*/
DQ = 2 ;
REQUEST[1] = 1 ;
REQUEST[2] = 0 ;
REQUEST[3] = 2 ;
/*
ALLOCATION[DQ][1] += 1 ;
ALLOCATION[DQ][2] += 0 ;
ALLOCATION[DQ][3] += 2 ;
NEED[DQ][1] -= 1 ;
NEED[DQ][2] -= 0 ;
NEED[DQ][3] -= 2 ;
*/
Test_Printf();
}
int main(){
init();
Test_Printf();
Ask();
Try();
return 0 ;
}
测试文件:
5
3
7
0
5
1
3
0
3
2
2
0
2
0
9
3
0
0
2
2
2
2
2
1
2
1
4
0
3
0
3
2
3
3
2
大部分功能都已完成,只剩下加注释和 修改UI了
大家可以参考下。