sort() /* 建立对进程进行优先级排列函数*/ {
PCB *first, *second; int insert=0;
if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/ { p->link=ready; ready=p; }
else /* 进程比较优先级,插入适当的位置中*/ { first=ready; second=first->link; while(second!=NULL) { if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/ { /*插入到当前进程前面*/ p->link=second; first->link=p; second=NULL; insert=1; } else /*向后移动指针*/ { first=first->link; second=second->link; } }
/* 插入进程优先数最低,则插入到队尾*/
if(insert==0) first->link=p; } }
input() /* 建立进程控制块函数*/ {
int i,num;
clrscr(); /*清屏*/
printf(\请输入进程号?\ scanf(\ for(i=0;i 33 printf(\输入进程名:\ scanf(\ printf(\输入进程优先数:\ scanf(\ printf(\输入进程运行时间:\ scanf(\ printf(\ p->rtime=0;p->state='w'; p->link=NULL; sort(); /* 调用sort函数*/ } } int space() { int l=0; PCB* pr=ready; while(pr!=NULL) { l++; pr=pr->link; } return(l); } disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ { printf(\ printf(\ printf(\ printf(\ printf(\ printf(\ printf(\ } check() /* 建立进程查看函数 */ { PCB* pr; printf(\当前正在运行的进程是:%s\显示当前运行进程*/ disp(p); pr=ready; printf(\当前就绪队列状态为:\\n\显示就绪队列状态*/ while(pr!=NULL) { disp(pr); 34 pr=pr->link; } } destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/ { printf(\进程 [%s] 已完成.\\n\ free(p); } running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ { (p->rtime)++; if(p->rtime==p->ntime) destroy(); /* 调用destroy函数*/ else { (p->super)--; p->state='w'; sort(); /*调用sort函数*/ } } main() /*主函数*/ { int len, h=0; char ch; input(); len=space(); while((len!=0)&&(ready!=NULL)) { ch=getchar(); h++; printf(\ p=ready; ready=p->link; p->link=NULL; p->state='R'; check(); running(); printf(\按任一键继续......\ ch=getchar(); } printf(\进程已经完成.\\n\ ch=getchar(); 35 } 3.1.3 参考题目 (1)编写并调试一个模拟的进程调度程序,采用―最高优先数优先‖调度算法对五个进程进行调度。 ―最高优先数优先‖调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。 静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。 动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1。或者进程等待的时间超过某一时限时增加其优先数的值,等等。 (2)编写并调试一个模拟的进程调度程序,采用―轮转法‖调度算法对五个进程进行调度。 轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。 简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还为完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。 实验总结 36 3.2 死锁检测算法 3.2.1 实验目的 采用银行家算法来预防死锁是可靠的,但也是非常保守的,因为它限制了进程对资源的存取,从而降低了进程的并发运行程度。死锁检测并不限制进程对资源的申请,只要有,就分配,但这也可能造成死锁。但由于死锁并不是经常发生的,故大大提高了系统运行的效率。通过本实验,可使学生进一步加深理解和掌握死锁的检测算法。 3.2.2 实验题目 两个题目任选其一: 1、编写对每种类型多个资源的死锁检测算法。 2、使用检测―进程—资源循环等待链‖的方法,编写死锁检测算法(有参考代码) 3.2.3 实验要求 题目1: (1) 死锁检测算法的数据结构参考教材死锁检测内容的现有资源矩阵E、可用资源矩 阵A、当前分配矩阵C、进程请求资源矩阵R。 (2) 完成对图3-1的死锁检测算法例子的测试。 (3) 完成在图3-1基础上,修改进程2的请求分别为 2 1 0 1 下的死锁检测。 图3-1 资源与分配矩阵 题目2: (1) 利用―进程—资源循环等待链‖的方法,编写死锁检测算法的具体方法可参考教 材的算法,在了解此算法思想的基础上,也可参考给定代码;具体代码描述参见3.3.5。 (2) 对图3-2中的资源分配图完成对该算法的测试。 37