📄 sun.cpp
字号:
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAXPRI 100
#define MAX 9
#define NIL -1
#define USE 0
#define UNUSE -1
struct {
int id;//进程身份(即:内部标识符,如:0,1,2)
char status;//进程状态,可为E、R、T、W和C;
//系统为进程设置了5种运行状态:
//E -- 执行态;
//R -- 高就绪态;
//T -- 低就绪态(执行进程因时间片到限而转入);
//W -- 等待态;
//C -- 完成态。
//各进程的初始状态均设置为R。
int nextwr; //等待链指针,指示在同一信号量上等待的下一个进程的标识数。
int priority;//进程优先数;
int flags; //用于标志此PCB是否可用:
//(USE表示PCB已创建 or UNUSE表示PCB未创建)
int identify;//外部标识符
}
pcb[MAX]; //PCB[i]的信息
struct {
int value; //信号量值,初值为1
int firstwr;//等待链首指针,指示该信号量上等待的第一个进程的标识数
}
sem[2]; //信号量的信息
struct {
int comer; //信息发送者(send message)
int info_num;//发来得信息数(messages's number)
int mutex; //信箱同步信号量(USE表示信箱可使用 or UNUSE表示信箱不可使用)
int boxflag;//信箱存在否的标志
}
box[MAX]; //进程i的信箱
char savearea[MAX][4],addr;//现场保留区,用数组SAVEAREA[MAX][4]表示。
//即每个进程都有一个大小为4个单元的保留区,用来保存被"中断"时的现场信息,
//如通用寄存器的内容和断点地址等。
int s1,s2;
//两个公共变量,用作共享临界资源。
int i; //用来模拟一个通用寄存器;
int seed;
int exe=NIL;//执行进程指针,其值为进程标识数;
int count[MAX+1];//可用PCB索引:
//其中:count[0..MAX-1]分别标识pcb[0..MAX-1](1为存在,0反之)
//count[MAX]为还可创建的PCB个数
int remark=1; //用于记录外部标识符的标识数
int wentdown[3*MAX];//用于记录已撤消的进程号
int cx;//已撤消的进程数组计数器
//***函数声明***
void init(); //初始化创建原语
int find(); //从就绪队列中选择一进程变为执行态
int p (int se,char ad); //p操作
int v (int se, char ad); //v操作
void create(); //创建原语
void deleted(int n); //撤消原语
void block (int se); //阻塞原语
void wakeup (int se); //唤醒原语
void eexit (int n); //进入终止态
void process(); //各进程须完成的操作流程
int scheduler(); //操作系统的进程调控
void analyse(); //判断是否添加新进程
bool timeint(char ad); //时间片中断函数
void time_silk(); //时间片单元函数(细分时间片到每一步)
void call_time(); //调用时间函数
void inform(); //发送消息函数(进程通信)
void recive(); //接收消息函数
//***
void init() // Initialization
{
//%%%%%为进程创建PCB %%%%%
for(int j=0; j<3; j++)
{
pcb[j].id =j; //给进程身份(如:1,2,3...)赋值
pcb[j].status ='r';//进程状态(可为E、R、T、W和C)
//R -- 高就绪态;
pcb[j].nextwr =NIL;//等待链指针,指示在同一信号量上等待的下一个进程的标识数。
printf("\n Process %d priority?",j+1);//***输入各进程优先级***
scanf("%d",&i);
pcb[j].priority=i; //***
pcb[j].identify=j+1;//外部标识符
pcb[j].flags=USE; //标识PCB已创建
count[j]=1; //***修改'可用PCB索引'***
count[3]--; //*****
remark++; //修改'外部标识符的标识数'的记录
box[j].mutex=USE;//信箱可使用
box[j].boxflag=USE;
}
//%%%%%————————%%%%%
//#####为各信号量赋初值#####
sem[0].value=1;
sem[0].firstwr=NIL;
sem[1].value=1;
sem[1].firstwr=NIL;
//#####————————#####
for(i=0; i<MAX; i++) //***现场保留区,\
//用数组SAVEAREA[MAX][4]表示***
for(j=0; j<4; j++)
savearea[i][j]='0'; //***
for(j=0;j<3*MAX;j++) //***已撤消的进程数组为空***
wentdown[j]=-1; //***
cx=0;
//&&&&&&&&-------------&&&&&&&&&&&
for(j=3;j<MAX;j++) //********给不存在的PCB,BOX及未用对应PCB索引赋值*********
{
pcb[j].status ='c';
pcb[j].flags=UNUSE;
box[j].mutex=USE;
box[j].boxflag=UNUSE;
pcb[j].identify=-1;
}
for(j=3;j<MAX;j++)
{
count[j]=0;
} //**************************
//&&&&&&&&--------------&&&&&&&&&&
count[MAX]=MAX-3; //还创建的PCB个数
}
double random() //产生随机数的程序,表明各进程行动的异步性
{
int m;
if(seed<0) m=-seed;
else m=seed;
seed=(25173 * seed +13849) % 65536;
return (m / 32767.0);
}
bool timeint (char ad) /* Time slice interrupt */
{
double x;
x=random();
for(double yi=0.00;yi<1.00;yi+=(1.00/MAX))
if((x<yi)&&(exe==(yi*MAX))) return (FALSE);
//***现场保留区***
savearea[exe][0]=i; //记录程序执行到的地方(即:该程序执行到了第几圈)
savearea[exe][1]=ad;//记录时间片用完时程序所处的状态
pcb[exe].status='t';//PCB中记录程序因Time slice用完而中断
//******
printf("\tTime slice interrupt .\n\tprocess %d enter into ready.\n",pcb[exe].identify);
exe=NIL; //记录当前正在运行的进程为无
return (TRUE);
}
int scheduler ()
{
int pd;
if(count[MAX]!=0) //分析是否创建进程
analyse();
if((pd = find()) == NIL && exe == NIL) //判断是否退出系统
return (NIL); /* Quit system */
if(pd != NIL)
{
if(exe == NIL)//***若当前执行程序为无***
{
pcb[pd].status='e';//将状态变为执行态
exe=pd;
call_time(); //调用时间
printf("Process %d is executing.\n",pcb[exe].identify);
recive(); //收消息
inform(); //发消息
} //******
else //***若当前执行程序非空***
if(pcb[pd].priority < pcb[exe].priority)//@@@判断优先级高低@@@
//若优先级高于当前执行程序
{
pcb[exe].status='r';
printf("\tProcess %d enter into ready.\n",pcb[exe].identify);
pcb[pd].status='e'; //将状态变为执行态
exe=pd;
call_time(); //调用时间
printf("Process %d is executing.\n",pcb[exe].identify);
recive(); //收消息
inform(); //发消息
} //@@@@@@
}
i =savearea[exe][0]; //恢复程序执行到的地方(圈数)
addr=savearea[exe][1];
return (exe);
}
int find() //~~~~~寻找应该吊为执行程序的进程~~~~~
{
int j; //用于循环计数
int pd=NIL;//记录应吊为执行态的进程
int w=MAXPRI;//设置一个哨兵来寻找最高优先的进程
for(j=0; j<MAX; j++) //*****判断是否存在高就绪*****
if(pcb[j].status == 'r')
if(pcb[j].priority < w)
{
w =pcb[j].priority;
pd=j;
} //**********
if(pd == NIL) //*****若不存在高就绪,则判断是否存在低就绪*****
for(j=0; j<MAX; j++)
if(pcb[j].status == 't')
if(pcb[j].priority < w)
{
w =pcb[j].priority;
pd=j;
} //**********
return (pd);//返回应吊为执行态的进程
}
int p (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 block (int se)
{
int w;
printf("\tProcess %d is block.\n",pcb[exe].identify);
pcb[exe].status='w'; //将程序PCB置为等待态
pcb[exe].nextwr=NIL; //等待链指针,\
//指示在同一信号量上等待的下一个进程的标识数
//***等待链首指针,指示该信号量上等待的第一个进程的标识数***
if((w = sem[se].firstwr) == NIL)
sem[se].firstwr=exe;
//***firstwr***
//等待链指针,指示在同一信号量上等待的下一个进程的标识数
else
{
while(pcb[w].nextwr != NIL)
w=pcb[w].nextwr;
pcb[w].nextwr=exe;
}
//***nextwr***
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -