作系统授课班级:11计本,11网工授课教师:梁宝华目录实验一进程管理 2 实验二存储器管理 9 实验三设备管理 16 实验四文件管理 21 实验五课程设计 27实验一进程管理//以下程序中有些错误,请找出并调试#include <stdio.h>#define TRUE 1#define FALSE 0#define MAXPRI 100#define NIL -1//进程控制块struct {int id; //进程号char status; //进程状态,'e'-执行态'r'-高就绪态't'-低就绪态'w'-等待态'c'-完成态int nextwr; //等待链指针,指示在同一信号量上等待的下一个等待进程的进程号。
int priority; //进程优先数,值越小,优先级越高。
int c;//进程中断次数}pcb[3];//共3个进程//s1、s2为三个进程共享的变量;seed为随机值;registeri模拟寄存器值,存放计算的重复次数。
int registeri,s1,s2,seed,exe=NIL;//exe为当前运行(占有cpu)的进程号//2个信号量sem[0]、sem[1],分别与共享变量s1、s2相联系。
//对应信号量sem[0]、sem[1]分别有两个阻塞队列,队列首由sem[].firstwr指定,队列链指针是pcb[].nextwrstruct{int value;//信号量值int firstwr;//等待该信号量的阻塞队列的首个进程号}sem[2];//三个进程的现场保留区,其中savearea[][0]为寄存器内容,savearea[][1]为下一条指令地址。
char savearea[3][4];char addr;//当前执行程序的当前指针void main();void init();float random();int timeint(char ad);int scheduler();int find();int p(int se,char ad);void block(int se);int v(int se,char ad);void wakeup(int se);void process1();void process2();void process3();void eexit(int n);//--------------------------------------------------------------------//主程序void main(){int currentProcess;printf("进程管理器\n");init();printf("s1=%d,s2=%d\n",s1,s2);printf("进程1、进程2、进程3已经准备好!\n");for (;;){currentProcess=scheduler(); //进程调度,选择优先级别最高的就绪进程运行。
if (currentProcess==NIL)break; //所有进程已经运行完毕,结束。
switch (currentProcess) //运行当前进程代码{case 0:break;case 1:process2();break;case 2:process3();break;default:printf("进程号出错!\n");break;}}printf("最后结果:s1=%d,s2=%d\n",s1,s2);}//------------------------------------------------------------------------ //初始化void init(){int i,j;s1=0;s2=0;//生成进程控制块for (j=0;j<3;j++){pcb[j].id=j; //进程号pcb[j].status='r'; //进程初始状态为高就绪状态pcb[j].nextwr=NIL;printf("\n进程%d 的优先数?",j+1);scanf("%d",&i);pcb[j].priority=i; //进程优先级pcb[j].c=0;}//初始化两个信号量sem[0].value=1;//与s1相联系sem[0].firstwr=NIL;sem[1].value=1;//与s2相联系sem[1].firstwr=NIL;//初始化现场保留区。
每个进程均有现场保留区。
for (i=1;i<3;i++)for (j=0;j<4;j++)savearea[i][j]='0';} //end of init()//生成0~1之间随机值float random(){int m;if (seed<0) m=-seed;else m=seed;seed=(25173*seed+13849)%65536;return (m/32767.0);}//----------------------------------------------------------------------------------//检测当前进程的时间片是否已到。
未到,返回FALSE,否则返回TRUE。
系统采用分时执行,//规定每个进程的执行概率为33%,用产生数x模拟时间片。
//ad为程序的当前语句地址。
int timeint(char ad){float x;x=random();if ((x<0.33)&&(exe==0)) return (FALSE);//当前进程为进程1,时间片未到。
if ((x>=0.33)&&(x<0.66)&&(exe==1)) return (FALSE);//当前进程为进程2,时间片未到。
if ((x>=0.66)&&(x<1)&&(exe==2)) return (FALSE);//当前进程为进程3,时间片未到。
//时间片已到处理:置正在执行进程状态为低就绪,处理器空闲。
savearea[exe][0]=registeri;//保存通用寄存器内容savearea[exe][1]=ad;//保存程序指针pcb[exe].status='t';//状态改为低就绪态printf("时间片中断,进程%d转入就绪态\n",exe+1);exe=NIL;return (TRUE);}//-----------------------------------------------------------------------------------//进程调度:选择一个进程投入运行。
返回当前进程的进程号。
int scheduler(){int pd;//选择投入运行的进程pdif ((pd=find())==NIL && exe==NIL)return (NIL);//无进程可运行,将结束。
if (pd!=NIL){if (exe==NIL) //选中了进程且处理器空闲,则投入运行。
{pcb[pd].status='e';exe=pd;printf("进程%d正在执行\n",exe+1);}else if (pcb[pd].priority<pcb[exe].priority)//选中进程的优选级别高于当前进程{//将当前进程转入高就绪状态pcb[exe].status='r';printf("进程%d进入就绪状态\n",exe+1);//选中进程pd投入执行pcb[pd].status='e';exe=pd;printf("进程%d正在执行\n",exe+1);}}//恢复进程现场registeri=savearea[exe][0];//恢复当前进程的寄存器。
addr=savearea[exe][1];//恢复执行进程的程序指针//修改优先权if(pcb[pd].c==3){pcb[pd].c=0;pcb[pd].priority=0;printf("\n!!进程%d中断次数达到3,优先级提高\n",pd+1);}return (exe);//返回当前进程的进程号}//---------------------------------------------------------------------------------//在3个进程中按就绪状态及其优先数选出进程。
返回选出的进程号。
int find(){int j,pd=NIL,w=MAXPRI;for (j=0;j<3;j++) //选择高就绪状态优先级最高的进程{if ((pcb[j].status=='r') && (pcb[j].priority<w)){w=pcb[j].priority;pd=j;}}if (pd==NIL) //没有高就绪状态的进程,寻找低就绪状态的进程。
{for (j=0;j<3;j++){if ((pcb[j].status=='t') && (pcb[j].priority<w)){w=pcb[j].priority;}}}return (pd);}//--------------------------------------------------------------------------------------//P操作,申请资源。
若申请se号资源成功,返回FALSE,若失败,把当前进程挂入se号资源的阻塞队列,//让出cpu,返回TRUE.//se为资源号,ad为程序当前指令的地址。
int p(int se,char ad){if (--sem[se].value>=0)return (FALSE);//资源申请成功//资源申请失败处理:block(se);//把当前进程挂入se号资源的阻塞队列savearea[exe][0]=registeri;//保存当前进程的寄存器内容savearea[exe][1]=ad;//保存当前进程的下一条指令地址exe=NIL;//让出CPUreturn (TRUE);//资源申请失败}//----------------------------------------------------------------------------//把当前进程阻塞,并挂到资源se的阻塞队列。