您好,欢迎访问三七文档
实验名称:进程管理实验要求:阅读后面的C语言实例,修改程序,使其优先数在运行期间可以变化(动态优先数)。例如,当某进程被时间片中断次数增加到一定数目时,提高其优先权。关键问题:读懂源程序代码,了解进程管理的方式,并设计一个算法使程序能在运行过程中修改进程优先级。设计思路:在进程控制块中定义一个记录进程中断次数的变量,在block函数中设置跟踪并记录进程中断次数,在调度函数schedule中设置算法,在进程中断3次后将该进程的优先级提升至最高。改动后的代码:#includestdio.h#defineTRUE1#defineFALSE0#defineMAXPRI100#defineNIL-1//进程控制块struct{intid;//进程号charstatus;//进程状态,'e'-执行态'r'-高就绪态't'-低就绪态'w'-等待态'c'-完成态intnextwr;//等待链指针,指示在同一信号量上等待的下一个等待进程的进程号。intpriority;//进程优先数,值越小,优先级越高。intc;//进程中断次数}pcb[3];//共3个进程//s1、s2为三个进程共享的变量;seed为随机值;registeri模拟寄存器值,存放计算的重复次数。intregisteri,s1,s2,seed,exe=NIL;//exe为当前运行(占有cpu)的进程号//2个信号量sem[0]、sem[1],分别与共享变量s1、s2相联系。//对应信号量sem[0]、sem[1]分别有两个阻塞队列,队列首由sem[].firstwr指定,队列链指针是pcb[].nextwrstruct{intvalue;//信号量值intfirstwr;//等待该信号量的阻塞队列的首个进程号}sem[2];//三个进程的现场保留区,其中savearea[][0]为寄存器内容,savearea[][1]为下一条指令地址。charsavearea[3][4];charaddr;//当前执行程序的当前指针voidmain();voidinit();floatrandom();inttimeint(charad);intscheduler();intfind();intp(intse,charad);voidblock(intse);intv(intse,charad);voidwakeup(intse);voidprocess1();voidprocess2();voidprocess3();voideexit(intn);//--------------------------------------------------------------------//主程序voidmain(){intcurrentProcess;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)//运行当前进程代码{case0:process1();break;case1:process2();break;case2:process3();break;default:printf(进程号出错!\n);break;}}printf(最后结果:s1=%d,s2=%d\n,s1,s2);}//------------------------------------------------------------------------//初始化voidinit(){inti,j;s1=0;s2=0;//生成进程控制块for(j=0;j3;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;i3;i++)for(j=0;j4;j++)savearea[i][j]='0';}//endofinit()//----------------------------------------------------------------------------------//生成0~1之间随机值floatrandom(){intm;if(seed0)m=-seed;elsem=seed;seed=(25173*seed+13849)%65536;return(m/32767.0);}//----------------------------------------------------------------------------------//检测当前进程的时间片是否已到。未到,返回FALSE,否则返回TRUE。系统采用分时执行,//规定每个进程的执行概率为33%,用产生数x模拟时间片。//ad为程序的当前语句地址。inttimeint(charad){floatx;x=random();if((x0.33)&&(exe==0))return(FALSE);//当前进程为进程1,时间片未到。if((x=0.33)&&(x0.66)&&(exe==1))return(FALSE);//当前进程为进程2,时间片未到。if((x=0.66)&&(x1)&&(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);}//-----------------------------------------------------------------------------------//进程调度:选择一个进程投入运行。返回当前进程的进程号。intscheduler(){intpd;//选择投入运行的进程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);}elseif(pcb[pd].prioritypcb[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个进程中按就绪状态及其优先数选出进程。返回选出的进程号。intfind(){intj,pd=NIL,w=MAXPRI;for(j=0;j3;j++)//选择高就绪状态优先级最高的进程{if((pcb[j].status=='r')&&(pcb[j].priorityw)){w=pcb[j].priority;pd=j;}}if(pd==NIL)//没有高就绪状态的进程,寻找低就绪状态的进程。{for(j=0;j3;j++){if((pcb[j].status=='t')&&(pcb[j].priorityw)){w=pcb[j].priority;pd=j;}}}return(pd);}//--------------------------------------------------------------------------------------//P操作,申请资源。若申请se号资源成功,返回FALSE,若失败,把当前进程挂入se号资源的阻塞队列,//让出cpu,返回TRUE.//se为资源号,ad为程序当前指令的地址。intp(intse,charad){if(--sem[se].value=0)return(FALSE);//资源申请成功//资源申请失败处理:block(se);//把当前进程挂入se号资源的阻塞队列savearea[exe][0]=registeri;//保存当前进程的寄存器内容savearea[exe][1]=ad;//保存当前进程的下一条指令地址exe=NIL;//让出CPUreturn(TRUE);//资源申请失败}//----------------------------------------------------------------------------//把当前进程阻塞,并挂到资源se的阻塞队列。voidblock(intse){intw;inti;i=(se==0)?1:2;printf(进程%d申请s%i时被阻塞\n,exe+1,i);pcb[exe].status='w';//当前进程被阻塞pcb[exe].c++;printf(进程%d中断次数+1,当前为%d\n,exe+1,pcb[exe].c);pcb[exe].nextwr=NIL;if((w=sem[se].firstwr)==NIL)//se资源的阻塞队列空,w为队列的首个进程号。sem[se].firstwr=exe;//当前进程为阻塞队列第一个进程else{while(pcb[w].nextwr!=NIL)//寻找队列的最后一个进程ww=pcb[w].nextwr;pcb[w].nextwr=exe;//将阻塞进程挂到队列尾部}}//---------------------------------------------------------------------------------------------//V操作,释放资源se。若无进程等待se资源,返回FALSE;若有进程等待se资源,将该等待进程置为高就绪状态,//保存当前进程现场,返回TRUE(将引起重新调度).//se为资源号,ad为当前指令的地址。intv(intse,charad){if(++sem[se].value0)return(FALSE);//释放资源后,无等待该资源的进程,返回。//有进程在等待该资源,则唤醒它。wakeup(se);//唤醒等待资源se的进程。//保存当前进程(执行态)的现场,因
本文标题:进程管理实验报告
链接地址:https://www.777doc.com/doc-5329394 .html