(环境:VMware软件下的Ubuntu虚拟机)(使用c语言)
如何基于“银行家”算法,设计一个死锁避免系统。
问题描述:初始情况下,所有进程的Allocation均是0,NEED=MAX。在每个时刻,系统中的部分进程会随机地发出一组资源请求,使用银行家算法决定是否可以响应其中某些进程的请求,若可以响应则为这些进程分配其申请的资源,若不能则该时刻不为其分配资源。若分配后某个进程的NEED已经变成0,则认为该进程已经结束,系统回收其已获得的所有资源且下一时刻不再进行资源请求。剩余进
程下一时刻继续重复这一过程,直到所有进程的NEED矩阵变成0。
要求:每时刻进程发出的请求要求是随机的(应小于或等于NEED)。系统应该显示每个时刻的请求响应情况、资源回收情况以及响应之后的资源状态等信息。系统中的时刻可以用一个timenow计数。
(1)若某时刻有两个及以上进程同时发出资源请求,应分别判定哪些进程可以被响应,哪些不能响应。
2)如果响应某进程的资源请求,必须输出安全序列。
3)无论进程的资源请求是否满足,每次判定后输出资源状态表。
4)程序结束时,应汇总输出每个时刻被响应的进程号和资源请求。
5)请给出调试代码过程图片。
要求:参考实验代码。在调试阶段使用确定数据,测试阶段再改为随机数据。应提前确保进程随机发出的请求是合法的,再去用银行家算法判定。将安全性检测算法中的finish数组的true/false改为进程号,即可输出安全序列。定义一个合适的数据结构来存放每时刻被响应的进程请求情况。
注意:
1)实验原理必须讲清楚银行家算法的原理。2)设计方案中应该系统框架图或者算法伪代码。3)实验报告中必须要有对能够验证验收要点各部分的运行结果要截图,通过分析验证程序设计的正确性
银行家代码附下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
//#include<sys/syscall.h>
#define PNUM 5
#define RNUM 3
int allocation[PNUM][RNUM]= {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
int max[PNUM][RNUM]= {{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
int need[PNUM][RNUM]= {{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
int available[RNUM]= {10,5,7};
void display() {
printf("The resource state now:\n");
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n","process"," max","allocation"," need","available");
for(int i=0; i<PNUM; i++) {
int j=0;
printf("P%-9d\t",i);
for(j=0; j<RNUM; j++)
printf("%2d ",max[i][j]);
printf("\t");
for(j=0; j<RNUM; j++)
printf("%2d ",allocation[i][j]);
printf("\t");
for(j=0; j<RNUM; j++)
printf("%2d ",need[i][j]);
printf("\t");
if(i==0)
for(j=0; j<RNUM; j++)
printf("%2d ",available[j]);
printf("\n");
}
}
void rollback(int req[],int id) {
int j=0;
for(j=0; j<RNUM; j++) { //rollback if a process's request is not allowed
allocation[id][j]-=req[j];
need[id][j]+=req[j];
available[j]+=req[j];
}
}
void request(int req[],int id) { //resource request
int j=0;
///////update state
for(j=0; j<RNUM; j++) {
allocation[id][j]+=req[j];
need[id][j]-=req[j];
available[j]-=req[j];
}
}
bool issafe() {
int work[RNUM];
bool finish[PNUM];
int i=0,j=0;
for(i=0; i<PNUM; i++)
finish[i]=false;
for(j=0; j<RNUM; j++)
work[j]=available[j];
///////is safe state?
int num= PNUM,flag=0;
while ( num-- && flag!=PNUM ){
for (i=0;i<PNUM;i++){
if ( finish[i]==true ) continue;
for ( j=0;j<RNUM;j++){
if ( need[i][j]>work[j] ) break;
}
if ( j==RNUM ) {
flag++;
for ( j=0;j<RNUM;j++){
work[j]+=allocation[i][j];
}
finish[i]=true;
}
}
}
if ( flag==PNUM ) return true;
else return false;
}
bool banker() {
int request[RNUM]={0};
int i=0,j=0,id;
while(true)
{
printf("Please input a process id :\n P");
scanf("%d",&id);
if(id<0||id>=PNUM) {printf("invalid process!\n");break;}
printf("Please input request array for P%d :\n",id);
for(j=0;j<RNUM;j++)
{
scanf("%d",&request[j]);
if(request[j]<0) {printf("invalid request!\n");return false;}
}
//////////banker algorithm
for ( j=0;j<RNUM;j++ ){
if ( request[j]>need[id][j] ) {
printf("请求大于所需的资源\n"); break;
}
if ( request[j] > available[j] ){
printf("请求大于剩余资源\n");break;
}
}
if ( j==RNUM){
for ( i=0;i<RNUM;i++){
available[i]-=request[i];
allocation[id][i]+=request[i];
need[id][i]-=request[i];
}
if(issafe()==false) {
rollback(&request[0],id);
printf("该请求会造成不安全\n");
} else if(issafe()==true) {
printf("可以申请,结果如下\n");
display();
}
}
}
}
int main() {
pid_t pid0,pid1,pid2,pid3,pid4;
while((pid0=vfork())==-1);
if(pid0==0) { //p0 allocation
printf("P0 is allocated<0,1,0>\n");
allocation[0][0]=0;
allocation[0][1]=1;
allocation[0][2]=0;
for(int i=0; i<RNUM; i++) {
need[0][i]=max[0][i]-allocation[0][i];
available[i]-=allocation[0][i];
}
exit(0);
} else { //main process
while((pid1=vfork())==-1);
if(pid1==0) { //p1 allocation
printf("P1 is allocated<2,0,0>\n");
allocation[1][0]=2;
allocation[1][1]=0;
allocation[1][2]=0;
for(int i=0; i<RNUM; i++) {
need[1][i]=max[1][i]-allocation[1][i];
available[i]-=allocation[1][i];
}
exit(0);
} else { //main process
while((pid2=vfork())==-1);
if(pid2==0) { //p2 allocation
printf("P2 is allocated<3,0,2>\n");
allocation[2][0]=3;
allocation[2][1]=0;
allocation[2][2]=2;
for(int i=0; i<RNUM; i++) {
need[2][i]=max[2][i]-allocation[2][i];
available[i]-=allocation[2][i];
}
exit(0);
} else { //main process
while((pid3=vfork())==-1);
if(pid3==0) { //p3 allocation
printf("P3 is allocated<2,1,1>\n");
allocation[3][0]=2;
allocation[3][1]=1;
allocation[3][2]=1;
for(int i=0; i<RNUM; i++) {
need[3][i]=max[3][i]-allocation[3][i];
available[i]-=allocation[3][i];
}
exit(0);
} else { //main process
while((pid4=vfork())==-1);
if(pid4==0) { //p3 allocation
printf("P4 is allocated<0,0,2>\n");
allocation[4][0]=0;
allocation[4][1]=0;
allocation[4][2]=2;
for(int i=0; i<RNUM; i++) {
need[4][i]=max[4][i]-allocation[4][i];
available[i]-=allocation[4][i];
}
exit(0);
} else { //main process
display();
if(issafe()==true) printf("The system is safe now!\n");
else printf("The system is not safe\n");
//////test banker()
banker();
exit(0);
}
}
}
}
}
return EXIT_SUCCESS;;
}
提供参考实例【操作系统实验二死锁避免之银行家算法的模拟】,期望对你有所帮助,链接:https://blog.csdn.net/qq_52487066/article/details/127612514
#include <iostream>
using namespace std;
#define False 0
#define True 1
int Max[100][100]={0};
int Allocation[100][100]={0};
int Need[100][100]={0};
int Available[100]={0};
int Work[100]={0};
char name[100]={0};
int temp[100]={0};
int S=100,P=100;
int safequeue[100]={0};
int Request[100]={0};
void Showdata()
{
int i,j,k,l;
cout<<"\t资源分配情况\n"<<endl;
cout<<"\tMax"<<"\t已分配"<<"\tNeed"<<endl;
cout<<"\t";
for(j=0;j<3;j++)
{
for (i=0;i<S;i++)
{
cout<<name[i]<<" ";
}
cout<<"\t";
}
cout<<endl;
for(i=0;i<P;i++)
{
cout<<i<<"\t";
for (j=0;j<S;j++)
{
cout<<Max[i][j]<<" ";
}
cout<<"\t";
for (k=0;k<S;k++)
{
cout<<Allocation[i][k]<<" ";
}
cout<<"\t";
for (l=0;l<S;l++)
{
cout<<Need[i][l]<<" ";
}
cout<<endl;
}
cout<<"\nAvailable"<<endl;
for (i=0;i<S;i++)
{
cout<<name[i]<<" ";
}
cout<<endl;
for (i=0;i<S;i++)
{
cout<<Available[i]<<" ";
}
cout<<endl;
}
int Judgesafe()
{
int tempwork[100][100]={0};
int i,k=0,m,apply,Finish[100]={0};
int j;
int flag=0;
for (i=0;i<S;i++)
{
Work[i]=Available[i];
}
for(i=0;i<P;i++)
{
apply=0;
for(j=0;j<S;j++)
{
if (Finish[i]==False&&Need[i][j]<=Work[j])
{
apply++;
if(apply==S)
{
for(m=0;m<S;m++)
{
tempwork[i][m]=Work[m];
Work[m]=Work[m]+Allocation[i][m];
}
Finish[i]=True;
temp[k]=i;
i=-1;
k++;
flag++;
}
}
}
}
for(i=0;i<P;i++)
{
if(Finish[i]==False)
{
cout<<"系统不安全"<<endl;
return -1;
}
}
cout<<"系统是安全的"<<endl;
cout<<"分配的序列:";
for(i=0;i<P;i++)
{
cout<<temp[i];
if(i<P-1) cout<<"->";
}
cout<<endl;
return 0;
}
void Changedata(int flag)
{
for (int i=0;i<S;i++)
{
Available[i]=Available[i]-Request[i];
Allocation[flag][i]=Allocation[flag][i]+Request[i];
Need[flag][i]=Need[flag][i]-Request[i];
}
}
void Share()
{
int i,flag;
char ch='Y';
cout<<"输入请求资源的进程:"<<endl;
cin>>flag;
if (flag>=P)
{
cout<<"此进程不存在!"<<endl;
}
else
{
cout<<"输入此进程对各个资源的请求数量:"<<endl;
for (i=0;i<S;i++)
{
cin>>Request[i];
}
for (i=0;i<S;i++)
{
if (Request[i]>Need[flag][i])
{
cout<<"进程"<<flag<<"申请的资源大于它所需要的资源!"<<endl;
cout<<"分配不合理不予分配!"<<endl;
ch='N';
break;
}
else if (Request[i]>Available[i])
{
cout<<"进程"<<flag<<"申请的资源大于可利用的资源。"<<endl;
cout<<"分配不合理,不予分配!"<<endl;
ch='N';
break;
}
}
if (ch=='Y')
{
Changedata(flag);
if (Judgesafe()==-1)
{
cout<<"进程"<<flag<<"申请资源后,系统进入死锁状态,分配失败!"<<endl;
for (int i=0;i<S;i++)
{
Available[i]=Available[i]+Request[i];
Allocation[flag][i]=Allocation[flag][i]-Request[i];
Need[flag][i]=Need[flag][i]+Request[i];
}
}
//o
}
}
}
int main()
{
int i,j,p,s,number;
char tempstring;
cout<<endl;
cout<<"输入资源种类:"<<endl;
cin>>s;
S=s;
cout<<"输入资源的名称和数量:"<<endl;
for(i=0;i<s;i++)
{
cin>>tempstring>>number;
name[i]=tempstring;
Available[i]=number;
}
cout<<"输入进程的数量:"<<endl;
cin>>p;
P=p;
cout<<"输入各进程资源最大需求量:"<<endl;
for (i=0;i<p;i++)
{
for (j=0;j<s;j++)
{
cin>>Max[i][j];
}
}
cout<<"输入各进程资源已分配量:"<<endl;
for (i=0;i<p;i++)
{
for (j=0;j<s;j++)
{
cin>>Allocation[i][j];
Available[j]=Available[j]-Allocation[i][j];
}
}
for (i=0;i<p;i++)
{
for (j=0;j<s;j++)
{
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
Share();
Showdata();
Judgesafe();
return 0;
}