#include "stdio.h" /*进程课设*/
#include "stdlib.h"
#define TRUE 1 /*宏定义true,false,max,nil*/
#define FALSE 0
#define MAX 100
#define NIL -1
struct { int id; /*进程标识符*/
char name; /*进程名*/
char ch; /* ch是进程状态字,共有五种状态,E(执行态),R(低就绪态), T(高就绪态),W(等待态),C(完成态 )*/
int nextwr; /*等待链指针,指示在同一信号量上等待的下一个进程的标识符*/
int priority; /* priority是进程优先级 */
} pcb[3];
struct { int value ;
int firstwr;
} sem[2];
char savearea[3][4],addr; /*现场保存部分*/
int i,s1=0,s2=0,exe=NIL;
void xitong()
{printf(" ┏━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf(" ┃?●本进程系统为模拟三个用户进程互斥的过程●? ┃\n");
printf(" ┃ /* 只要求输入进程名和该进程的优先级 */ ┃\n");
printf(" ┗━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}
void init() /*初始化*/
{int j;
for ( j=0;j<3;j++)
{ printf("请输入进程%d的名称(单个英文字符) \n",j+1);
printf("→");
pcb[j].name=getchar();
getchar();
pcb[j].id=j;
pcb[j].ch='r';
pcb[j].nextwr=NIL;
printf("\n 请输入进程%d的优先级权是多少?\n", j+1);
scanf("%d",&i);
pcb[j].priority=i;
}
sem[0].value=1;
sem[0].firstwr=NIL;
sem[1].value=1;
sem[1].firstwr=NIL;
for(i=0;i<3;i++)
for (j=0;j<4;j++)
savearea[i][j]='0' ;
}
int rand1() /*产生随机数*/
{ int m;
// rand1();
m=rand();
printf("m=%d",m);
return (m);
}
bool timeint(char ad)
/*时间片中断*/
// char ad;
{ int x;
printf("ad=%c",ad);
x=rand1();
printf("x=%d",x);
if ( (x<0)&&(exe==0)) return(FALSE);
if ( (x<1)&&(exe==1)) return(FALSE);
if ( (x<2)&&(exe==2)) return(FALSE);
savearea[exe][0]=i; /*优先级*/
savearea[exe][1]=ad; /*随机数*/
pcb[exe].ch='t';
printf("\n");
printf("\n");
printf(" ★★★注意★★★ !!! 发生时间片中断!!!\n");
//sleep(3);
// clrscr();
//sleep(1);
//delay(6000000);
printf(" *****进程%d进入低就绪状态.*****\n",exe+1);
exe=NIL;
return(TRUE);
}
find()
{ int j,pd=NIL,w=MAX;
for (j=0;j<3;j++)
if (pcb[j].ch=='r')
if(pcb[j].priority<w)
{ w=pcb[j].priority;
pd=j;
}
if(pd==NIL)
for(j=0;j<3;j++)
if(pcb[j].ch=='t')
if(pcb[j].priority<w)
{ w=pcb[j].priority;
pd=j;
}
return(pd);
}
scheduler()
{ int pd;
if( (pd=find())==NIL && exe==NIL)
return(NIL);
if(pd!=NIL)
{ if(exe==NIL)
{ pcb[pd].ch='e';
exe=pd;
printf("********进程%d正在执行!!!*** ******\n",exe+1);
}
else if (pcb[pd].priority<pcb[exe].priority)
{ pcb[exe].ch='r';
printf(" 进程%d进入等待状态!\n" ,exe+1);
pcb[pd].ch='e';
exe=pd;
printf("****进程%d正在执行!!!*****\n",exe+1);
}
}
i=savearea[exe][0]; /*优先权*/
addr=savearea[exe][1]; /*地址*/
return(exe);
}
void block(int se) /*阻塞*/
//int se;
{ int w;
printf(" 进程%d 现在被阻塞,调用进程入等待队列!!\n",exe+1);
pcb[exe].ch='w';
pcb[exe].nextwr=NIL;
printf("当前在等待队列中的为第%d个进程\n",exe+1);
if((w=sem[se].firstwr)==NIL)
sem[se].firstwr=exe;
else { while(pcb[w].nextwr!=NIL)
w=pcb[w].nextwr;
pcb[w].nextwr=exe;
}
getchar();
}
p (int se,char ad)
//int se;
//char ad;
{ if (--sem[se].value>=0) return(FALSE);
block(se);
savearea[exe][0]=i;
savearea[exe][1]=ad;
exe=NIL;
return(TRUE);
}
void wakeup(int se)
// int se;
{ int w;
w=sem[se].firstwr;
printf("从等待队列唤醒等待进程%d!",w+1);
if(w!=NIL)
{ sem[se].firstwr=pcb[w].nextwr;
pcb[w].ch='r';
printf(" 进程%d被唤醒!\n",w+1);
}
}
v(int se,char ad)
//int se;
//char ad;
{ if(++sem[se].value>0) return(FALSE);
wakeup(se);
savearea[exe][1]=ad;
savearea[exe][0]=i;
return(TRUE);
}
void eexit(int n) /*结束函数*/
// int n;
{ pcb[n].ch='c';
printf("______________进程%d被完成!!!________________\n",n+1);
exe=NIL;
}
void process1( )
{
if (addr=='a') goto a1;
if (addr=='b') goto b1;
if (addr=='c') goto c1;
if (addr=='d') goto d1;
if (addr=='e') goto e1;
if (addr=='f') goto f1;
for (i=1;i<6;i++)
{ printf("\n 现在开始调度进程一\n");
printf("进程一调用P信号1 !\n");
if(p(0,'a')) break; /*进程一被阻塞*/
a1: printf("进程一被执行使用临界资源 s1 !\n");
if (timeint('b')) break; /*时间片中断*/
b1: printf("s1=%d\n",++s1);
printf("进程一调用V信号1并且释放临界资源 s1 !\n");
if (v(0,'c')) break; /*唤醒一个阻塞进程*/
c1: printf("进程一调用P信号2 !\n");
if(p(1,'d')) break;
d1: printf("进程一被执行使用临界资源 s2 !\n");
if(timeint('e')) break;
e1: printf("s2=%d\n",++s2);
printf("进程一调用V信号 2并且释放临界资源 s2 !\n");
if (v(1,'f')) break; /*唤醒一个阻塞进程*/
f1: printf("##############进程一循环数=%d#################\n",i);
}
if(i<6) return;
eexit(0);
getchar();
}
void process2( )
{ if (addr=='a') goto a2;
if (addr=='b') goto b2;
if (addr=='c') goto c2;
if (addr=='d') goto d2;
if (addr=='e') goto e2;
if (addr=='f') goto f2;
for(i=1;i<6;++i)
{ printf("\n 现在开始调度进程二\n");
printf("进程二调用P信号2 !\n");
if(p(1,'a')) break; /*进程二被阻塞*/
a2: printf("**********进程二被执行使用临界资源 s2 ! \n");
if(timeint('b')) break;
b2: printf("s2=%d\n",++s2);
printf("进程二调用V信号2并且释放临界资源 s2 !\n");
if(v(1,'c')) break; /*唤醒一个阻塞进程*/
c2: printf("进程二调用P信号1!\n");
if(p(0,'d')) break; /*进程二被阻塞*/
d2: printf("*********进程二被执行使用临界资源 s1!\n");
if(timeint('e')) break;
e2: printf("s1=%d\n",++s1);
printf("进程二调用V信号 1 并且释放临界资源 s1 !\n");
if(v(0,'f')) break; /*唤醒一个阻塞进程*/
f2: printf("################进程二循环数=%d##############\n",i);
}
if(i<6) return;
eexit(1);
getchar();
}
void process3( )
{
if(addr=='a') goto a3;
if(addr=='b') goto b3;
if(addr=='c') goto c3;
for(i=1;i<6;++i)
{ printf("\n 现在开始调度进程三\n");
printf("进程三调用P信号 2 !\n");
if(p(1,'a')) break; /*进程三被阻塞*/
a3: printf("进程三被执行使用临界资源 s1 !\n");
if(timeint('b')) break;
b3: printf("s2=%d\n",++s2);
printf("进程三调用V信号2释放临界资源s1 !\n");
if(v(1,'c')) break; /*唤醒一个阻塞进程*/
c3: printf("###############进程三循环数=%d#############\n",i);
}
if(i<6) return;
eexit(2);
getchar();
}
void pcb1()
{int i;
for(i=0;i<3;i++)
{printf("┏━━━━━━━━━━━━━━━━━┓\n");
printf("┃进程名 : %c进程 ┃\n",pcb[i].name);
printf("┃进程标识符: %d进程 ┃\n",pcb[i].id+1);
printf("┃进程状态 : %c ┃\n",pcb[i].ch);
printf("┃进程优先级: %d ┃\n",pcb[i].priority);
printf("┗━━━━━━━━━━━━━━━━━┛\n");
}
//delay(99999999999);
}
void main( )
{ int k;
//clrscr();
printf("******************进 程 管 理***************** \n\n");
xitong();
init( );
printf("!!!进程一,二,三以准备就绪,即将开始调度程序!!!\n");
printf("进程一,二,三现在的PCB控制块如下!!!\n");
pcb1();
for( ; ; )
if((k=scheduler( ))!=NIL)
switch(k)
{
case 0: process1( );
break;
case 1: process2( );
break;
case 2: process3( );
break;
default: printf("!!!进程标志符输入出错!!!\n");
break;
}
else break;
printf("§临界资源s1,s2调用的次数§\n");
printf(" s1=%d, s2=%d\n",s1,s2);
pcb1();
printf("\n********************END********************\n");
printf("☆☆☆☆☆☆☆谢谢使用,再见??☆☆☆☆☆☆☆\n");
}