《进程管理实验报告(共11页).doc》由会员分享,可在线阅读,更多相关《进程管理实验报告(共11页).doc(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上实验名称: 进程管理实验要求: 阅读后面的C语言实例,修改程序,使其优先数在运行期间可以变化(动态优先数)。例如,当某进程被时间片中断次数增加到一定数目时,提高其优先权。关键问题: 读懂源程序代码,了解进程管理的方式,并设计一个算法使程序能在运行过程中修改进程优先级。设计思路: 在进程控制块中定义一个记录进程中断次数的变量,在block函数中设置跟踪并记录进程中断次数,在调度函数schedule中设置算法,在进程中断3次后将该进程的优先级提升至最高。改动后的代码:#include #define TRUE 1#define FALSE 0#define MAXPRI
2、100#define NIL -1/进程控制块struct int id; /进程号 char status; /进程状态,e-执行态 r-高就绪态 t-低就绪态 w-等待态 c-完成态 int nextwr; /等待链指针,指示在同一信号量上等待的下一个等待进程的进程号。 int priority; /进程优先数,值越小,优先级越高。 int c;/进程中断次数 pcb3;/共3个进程/s1、s2为三个进程共享的变量;seed为随机值;registeri模拟寄存器值,存放计算的重复次数。int registeri,s1,s2,seed,exe=NIL;/exe为当前运行(占有cpu)的进程号
3、/2个信号量sem0、sem1,分别与共享变量s1、s2相联系。/对应信号量sem0、sem1分别有两个阻塞队列,队列首由sem.firstwr指定,队列链指针是pcb.nextwrstruct int value;/信号量值 int firstwr;/等待该信号量的阻塞队列的首个进程号sem2;/三个进程的现场保留区,其中savearea0为寄存器内容,savearea1为下一条指令地址。char savearea34;char addr;/当前执行程序的当前指针void main();void init();float random();int timeint(char ad);int s
4、cheduler();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=%dn,s1,s2); printf(进程1、进程2、进程3已经准备好!n); for (;) cur
5、rentProcess=scheduler(); /进程调度,选择优先级别最高的就绪进程运行。if (currentProcess=NIL) break; /所有进程已经运行完毕,结束。switch (currentProcess) /运行当前进程代码 case 0: process1(); break; case 1: process2(); break; case 2: process3(); break; default: printf(进程号出错!n); break; printf(最后结果:s1=%d,s2=%dn,s1,s2);/-/初始化void init() int i,j;
6、s1=0;s2=0; /生成进程控制块 for (j=0;j3;j+) pcbj.id=j; /进程号 pcbj.status=r; /进程初始状态为高就绪状态 pcbj.nextwr=NIL; printf(n进程 %d 的优先数?,j+1); scanf(%d,&i); pcbj.priority=i; /进程优先级 pcbj.c=0; /初始化两个信号量 sem0.value=1;/与s1相联系 sem0.firstwr=NIL; sem1.value=1;/与s2相联系 sem1.firstwr=NIL; /初始化现场保留区。每个进程均有现场保留区。 for (i=1;i3;i+) f
7、or (j=0;j4;j+)saveareaij=0; /end of init()/-/生成01之间随机值float random() int m; if (seed0) 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
8、)&(x=0.66)&(x1)&(exe=2) return (FALSE);/当前进程为进程3,时间片未到。 /时间片已到处理:置正在执行进程状态为低就绪,处理器空闲。 saveareaexe0=registeri;/保存通用寄存器内容 saveareaexe1=ad;/保存程序指针 pcbexe.status=t;/状态改为低就绪态 printf(时间片中断 ,进程%d转入就绪态n,exe+1); exe=NIL; return (TRUE);/-/进程调度:选择一个进程投入运行。返回当前进程的进程号。int scheduler() int pd; /选择投入运行的进程pd if (pd=
9、find()=NIL & exe=NIL) return (NIL);/无进程可运行,将结束。 if (pd!=NIL) if (exe=NIL) /选中了进程且处理器空闲,则投入运行。 pcbpd.status=e; exe=pd; printf(进程%d正在执行n,exe+1); else if (pcbpd.prioritypcbexe.priority)/选中进程的优选级别高于当前进程 /将当前进程转入高就绪状态 pcbexe.status=r; printf(进程%d进入就绪状态n,exe+1);/选中进程pd投入执行 pcbpd.status=e; exe=pd; printf(进
10、程%d正在执行n,exe+1); /恢复进程现场 registeri=saveareaexe0;/恢复当前进程的寄存器。 addr=saveareaexe1;/恢复执行进程的程序指针/修改优先权 if(pcbpd.c=3) pcbpd.c=0; pcbpd.priority=0; printf(n!进程%d中断次数达到3,优先级提高n,pd+1); return (exe);/返回当前进程的进程号/-/在3个进程中按就绪状态及其优先数选出进程。返回选出的进程号。int find() int j,pd=NIL,w=MAXPRI; for (j=0;j3;j+) /选择高就绪状态优先级最高的进程
11、if (pcbj.status=r) & (pcbj.priorityw) w=pcbj.priority;pd=j; if (pd=NIL) /没有高就绪状态的进程,寻找低就绪状态的进程。 for (j=0;j3;j+) if (pcbj.status=t) & (pcbj.priority=0) return (FALSE);/资源申请成功 /资源申请失败处理: block(se);/把当前进程挂入se号资源的阻塞队列 saveareaexe0=registeri;/保存当前进程的寄存器内容 saveareaexe1=ad;/保存当前进程的下一条指令地址 exe=NIL;/让出CPU re
12、turn (TRUE);/资源申请失败/-/把当前进程阻塞,并挂到资源se的阻塞队列。void block(int se) int w; int i; i=(se=0)?1:2; printf(进程%d申请s%i时被阻塞n,exe+1,i); pcbexe.status=w;/当前进程被阻塞 pcbexe.c+; printf(进程%d中断次数+1,当前为%dn,exe+1,pcbexe.c); pcbexe.nextwr=NIL; if (w=semse.firstwr)=NIL)/se资源的阻塞队列空,w为队列的首个进程号。 semse.firstwr=exe;/当前进程为阻塞队列第一个进
13、程 else while(pcbw.nextwr!=NIL)/寻找队列的最后一个进程w w=pcbw.nextwr; pcbw.nextwr=exe;/将阻塞进程挂到队列尾部 /-/V操作,释放资源se。若无进程等待se资源,返回FALSE;若有进程等待se资源,将该等待进程置为高就绪状态,/保存当前进程现场,返回TRUE(将引起重新调度)./se为资源号,ad为当前指令的地址。int v(int se,char ad) if (+semse.value0) return (FALSE);/释放资源后,无等待该资源的进程,返回。 /有进程在等待该资源,则唤醒它。 wakeup(se);/唤醒等
14、待资源se的进程。 /保存当前进程(执行态)的现场,因为后面将引起处理器重新调度。 saveareaexe0=registeri;/保存寄存器 saveareaexe1=ad;/保存指令指针 return (TRUE);/-/将等待se资源的首个进程置为高就绪状态(唤醒)void wakeup(int se) int w; int i; i=(se=0)?1:2; w=semse.firstwr;/取资源se阻塞队列的首个进程w if (w!=NIL) semse.firstwr=pcbw.nextwr;/调整阻塞队列首指针 pcbw.status=r;/将w进程置为高就绪态 printf(进
15、程%d被唤醒,得到资源s%dn,w+1,i); /-/进程1的程序代码,完成5次的重复计算:s1=s1+1;s2=s2+1;/该程序退出后将进行重新调度。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 (registeri=1;registeri6;registeri+) /程序执行s1=s1+1计算: i
16、f (p(0,a) /申请s1对应信号量sem0。若申请失败 ,则当前进程被阻塞,a为中断地址,即下次恢复执行时地址。break;/退出。当前进程被阻塞。 /可以使用s1,但要检查时间片是否到限。a1: printf(进程1得到s1,正在临界区1n);if (timeint(b) /检查该进程的时间片是否到。若到,阻塞进程,b为中断地址。break;/退出,重新调度。/完成计算b1: printf(s1=%dn,+s1); /s1=s1+1 if (v(0,c) /释放信号量sem0。如有等待该信号量的进程,则退出。c为中断地址。break; /退出。重新调度。/程序执行s2=s2+1计算:c
17、1: if (p(1,d) /申请s2对应信号量。如申请失败 ,则当前进程被阻塞。break;/退出。当前进程阻塞。 /可以使用s2.d1: printf(进程1得到s2,正在临界区2n);if (timeint(e) /检查进程1的时间片是否到限。break; /时间片到限,退出。重新调度。 /使用s2e1: printf(s2=%dn,+s2); /s2=s2+1 if (v(1,f) /释放信号量break; /有进程等待该信号量,退出。重新调度。f1: printf(进程1循环计算次数=%dn,registeri); /for循环 if (registeri6) return; /计算
18、任务未完成 eexit(0);/任务完成。结束进程1。/-/进程2的程序代码,完成5次的重复计算:s2=s2+1;s1=s1+1;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 (registeri=1;registeri6;registeri+) /进程执行s2=s2+1计算:if (p(1,a) /申请s2对应信号量。若失败 ,当前
19、进程被阻塞。break;/退出。重新调度。 /可以使用s2a2: printf(进程2得到s2,正在临界区2n);if (timeint(b) /检查进程的时间片是否到限break;/ 时间片到,退出。重新调度。b2: printf(s2=%dn,+s2); /计算s2=s2+1 if (v(1,c) /释放信号量。break; /有进程正在等待该信号量,退出,重新调度。/进程执行s1=s1+1计算:c2: if (p(0,d) /申请s1对应信号量。若失败,进程被阻塞。break;/进程阻塞,退出,重新调度。 /可以使用s1d2: printf(进程2得到s1,正在临界区1n);if (ti
20、meint(e) /检查进程的时间片是否到。若到,阻塞进程。break; /时间片到,退出,重新调度。e2: printf(s1=%dn,+s1); / 计算s1=s1+1 if (v(0,f) /释放信号量。break; /有进程正在等待该信号量, 退出,重新调度。f2: printf(进程2循环计算次数=%dn,registeri); / for循环6次 if (registeri6) return; /计算未结束 eexit(1);/计算结束。停止进程2。/-/进程3的程序代码,完成5次的重复计算:s2=s2+1;void process3() if (addr=a) goto a3;
21、if (addr=b) goto b3; if (addr=c) goto c3; for (registeri=1;registeri6;registeri+) /进程执行s2=s2+1计算:if (p(1,a) /申请s2对应信号量。break;/退出 /可以使用s2a3: printf(进程3得到s2,正在临界区2n);if (timeint(b) /检查进程的时间片是否到break;/退出b3: printf(s2=%dn,+s2); /计算s2=s2+1 if (v(1,c) /释放信号量break; c3: printf(进程3循环计算次数=%dn,registeri); /for循环 if (registeri6) return; eexit(2);/结束进程3/-/进程结束。 n为进程号。void eexit(int n) pcbn.status=c;/置进程状态为完成态 printf(进程%d已经完成n,n+1); exe=NIL;/让出处理器专心-专注-专业