#include<stdio.h>
#include<stdlib.h>
#define resource 3//标示资源种类为3种
#define process 5//标示进程个数为5个
int is_security=0;
typedef struct node
{
char name;//进程名
int Max[resource];//标示进程资源需求总量
int Allocation[resource];//标示进程已分配的资源
int Need[resource];//标示进程还需要的资源
int securityflow;
struct node *next;
}linklist;
void main()
{
linklist *create(linklist *L,char n[],int m[process][resource],int a[process][resource]);
int judge(linklist *L,int currentsum[],int p,int ask_n[]);//该函数判断请求后是否安全
int security(linklist *L,int a[]);
void showsecurity(linklist *L);
int i,j,k=1,m[process][resource],a[process][resource];//对指针数值的初始化数组
int ask_p;//标示发出请求的进程代号,如1代表第一个进程
int ask_n[resource];//标示进程的请求向量
int currentsum[resource];//系统中当前的资源总量
int flag;//标志性变量,1表示分配后安全,0表示分配后会产生死锁,-1表示无法分配,-2表示请求大于所需
char n[resource];//n数组对应进程名
linklist *L;
L=(linklist *)malloc(sizeof(linklist));
printf("请输入系统中的资源总量:/n");
for(i=0;i<resource;i++)
{
printf("请输入第%d类资源的总量:",k++);
scanf("%d",¤tsum[i]);
}
k=1;
printf("请对进程名及其资源依次初始化:/n");
for(i=0;i<process;i++)
{
printf("进程名:");
fflush(stdin);
scanf("%c",&n[i]);
printf("请输入该进程的资源总需求量:/n");
for(j=0;j<resource;j++)
{
printf("请输入该进程对第%d类资源的总需求量:",k++);
scanf("%d",&m[i][j]);
}
k=1;
printf("请输入该进程的资源已分配量:/n");
for(j=0;j<resource;j++)
{
printf("请输入该进程对第%d类资源的已分配量:",k++);
scanf("%d",&a[i][j]);
currentsum[j]-=a[i][j];
}
k=1;
}
for(i=0;i<resource;i++)
printf("%d",currentsum[i]);
k=1;
L=create(L,n,m,a);
is_security=security(L,currentsum);
if(is_security==0) printf("这次分配不能找到安全序列/n");
if(is_security==1)
{
printf("这种原分配可以产生安全序列:");
showsecurity(L);
printf("请输入发出请求的进程代号,如1代表第一个进程:");
scanf("%d",&ask_p);
printf("请依次输入进程请求的资源数目:/n");
for(i=0;i<resource;i++)
{
printf("请输入第%d类资源的请求数量:",k++);
scanf("%d",&ask_n[i]);
}
flag=judge(L,currentsum,ask_p,ask_n);
switch(flag)
{
case 1:
{
printf("这样分配不会导致死锁/n");
showsecurity(L);
break;
}
case 0:printf("这样分配会导致死锁/n"); break;
case -1:printf("这样无法分配/n"); break;
case -2:printf("这样的请求大于所需/n"); break;
default:break;
}
}
}
linklist *create(linklist *L,char n[],int m[process][resource],int a[process][resource])
{
linklist *q,*s;
int i,j;
L=(linklist *)malloc(sizeof(linklist));
L->next=NULL;
s=L;
for(i=0;i<process;i++)
{
q=(linklist *)malloc(sizeof(linklist));
q->name=n[i];
for(j=0;j<resource;j++)
{
q->Max[j]=m[i][j];
q->Allocation[j]=a[i][j];
q->Need[j]=q->Max[j]-q->Allocation[j];
}
s->next=q;
s=q;
}
s->next=L;
return(L);
}
int judge(linklist *L,int currentsum[],int p,int ask_n[])
{
int security(linklist *L,int a[]);
linklist *q,*r;
int i,back;
int search=0;
q=L->next;
r=q->next;
for(i=1;i<p;i++) q=q->next;
for(i=0;i<resource;i++)
{
if(ask_n[i]>currentsum[i]) return(-1);
if(ask_n[i]>q->Need[i]) return(-2);
}
for(i=1;i<resource;i++)
{
currentsum[i]-=ask_n[i];
q->Allocation[i]+=ask_n[i];
q->Need[i]-=ask_n[i];
}
back=security(L,currentsum);
return(back);
}
int security(linklist *L,int a[])
{
int Work[resource],Finish[process];
int i,j,k=0,point;
int flag_N=1,flag_F=1;
int securityarray[process];
linklist *p,*h;
for(i=0;i<resource;i++) Work[i]=a[i];
for(i=0;i<process;i++)
{
Finish[i]=0;
securityarray[i]=0;
}
h=L;
p=L->next;
i=0;
while(p!=h)
{
flag_N=1;
if(Finish[i]==0)
{
for(j=0;j<resource;j++)
{
if(p->Need[i]>Work[i])
{
flag_N=0;
break;
}
}
if(flag_N!=0)
{
for(j=0;j<resource;j++) Work[j]+=p->Allocation[j];
Finish[i]=1;
securityarray[i]=k; k++;
h=p;
p=h->next;
}
}
i++;
if(i==process) i=0;
p=p->next;
if(p==L) p=p->next;
}
for(j=0;j<process;j++)
{
if(Finish[j]==0)
{
flag_F=0;
break;
}
printf("*");
}
if(flag_F==0) return(0);
if(flag_F==1)
{
p=L->next;
point=0;
while(p!=L)
{
p->securityflow=securityarray[point];
point++;
p=p->next;
}
return(1);
}
}
void showsecurity(linklist *L)
{
int count=process;
int check=0;
linklist *p;
p=L->next;
while(count>0)
{
if(p->securityflow==check)
{
printf("%c",p->name);
check++;
count--;
if(count==0) printf("/n");
else printf(",");
}
p=p->next;
}
}