id,&temp1->priority,&temp1-〉cputime,&temp1—〉alltime,&temp1->startblock,&temp1—〉blocktime,temp1-〉state); if(i==0) //如果创建的是第一个结点 { head=temp1; head—>next=NULL; continue; } if(head—〉priority 〈 temp1-〉priority) //如果创建结点中所保存的数比头结点所保存的数要大,则直接把该结点插入到头结点之前 { temp1—〉next=head; head=temp1; continue; } temp2=head; //temp2为比较结点的直接前驱结点 temp3=temp2—>next; //temp3为比较的结点功能 }
while(temp3!=NULL && temp3—>priority〉=temp1—>priority) //实现查找的{ temp2=temp3; temp3=temp2-〉next; }
temp2—〉next=temp1; temp1->next=temp3;
}
return head;
PCB *InsertQueue(PCB *head,PCB *run) //在就绪队列中插入一个结点 { PCB *temp1,*temp2; //temp1和temp2分别为比较结点的前驱和比较结点 if(head==NULL) //如果就绪队列为空 { head=run; head—>next=NULL; } else if(head—〉priority < run—〉priority) //如果插入结点中所保存的数比头结点所保存的数要大,则直接把该结点插入到头结点之前 { run->next=head; head=run; } else { temp1=head; //temp1为比较结点的直接前驱结点 temp2=temp1->next; //temp2为比较的结点 while(temp2!=NULL && temp2-〉priority〉=run-〉priority) //实现查找的功能 { temp1=temp2; temp2=temp1—>next; } temp1-〉next=run; run—>next=temp2; } return head; }
main() { int num; //num为进程的个数
int alltime=0; //用来保存所有进程需要占用的CPU时间 PCB *head; //head为就绪队列的头指针
PCB *run=NULL; //run为执行进程结点的指针 PCB *block=NULL; //block为阻塞进程的结点 PCB *temp;
printf(\"请输入进程的个数:”); scanf(\"%d\",&num); head=CreatQueue(num); getchar(); temp=head;
while(temp!=NULL) {
alltime+=temp—〉alltime; temp=temp—>next; } while(alltime 〉 0) { if(head!=NULL) { run=head; //把就绪队列中的第一个进程取出来执行 head=head—〉next; //就绪队列的头指针指向下一个结点 strcpy(run->state,\"run”); //状态改为执行 run->next=NULL; /*显示状态*/ printf(”RUNNING PROG:%d\\n”,run-〉id); //显示执行进程 printf(”READY_QUEUE:\"); //显示就绪进程 temp=head; while(temp!=NULL) { printf(”-〉%d”,temp->id); temp=temp-〉next; } printf(\"\\n\"); printf(”BLOCK_QUEUE:\"); //显示阻塞进程 if(block!=NULL) { printf(\"%d”,block—>id); } printf(”\\n”); printf(\"============================================================================\\n”); printf(”ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE\\n\");
printf(\"%d %d %d %d %d %d %s\\n\—>id,run—〉priority,run->cputime,run—〉alltime,run—>startblock,run->blocktime,run—〉state); temp=head; while(temp!=NULL) { printf(”%d %d %d %d %d %d %s\\n\—〉id,temp—>priority,temp—>cputime,temp-〉alltime,temp—〉startblock,temp-〉blocktime,temp->state); temp=temp—>next; } if(block!=NULL) { printf(”%d %d %d %d %d %d %s\—>id,block—〉priority,block->cputime,block-〉alltime,block-〉startblock,block->blocktime,block->state); } printf(\"\\n”); printf(”============================================================================\\n”); /*显示状态*/ /*改变优先数*/ run—>priority-=3; //执行进程的优先数减3 temp=head; 减1
while(temp!=NULL) //就绪进程的优先数加1
{ temp—>priority+=1; temp=temp-〉next; }
/*改变优先数*/
/*改变执行进程的有关参数*/
run->cputime+=1; //执行进程的已占用CPU时间加1 run—>alltime-=1; //还需要的CPU时间减1 if(run—〉alltime!=0) { if(run->startblock 〉 0) //如果该进程会被阻塞 { run-〉startblock-=1; //执行完一个时间片后,开始阻塞的时间
if(run—〉startblock==0) //如果阻塞的时间到了 { block=run; //执行转阻塞 strcpy(block—〉state,”b”); //状态转阻塞 alltime--;
printf(”\\n\"); continue; } } strcpy(run-〉state,\"r”); //状态转就绪 head=InsertQueue(head,run); //执行转就绪 run=NULL; }
/*改变执行进程的有关参数*/ alltime--; } else
{ /*显示状态*/ printf(\"RUNNING PROG:\\n”); //显示执行进程 printf(\"READY_QUEUE:\\n\"); //显示就绪进程 printf(\"BLOCK_QUEUE:\"); //显示阻塞进程 if(block!=NULL) { printf(\"%d\); } printf(\"\\n”);
printf(\"=====================================================================
=======\\n”); printf(\"ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE\\n\"); if(block!=NULL) { printf(”%d %d %d %d %d %d %s”,block-〉id,block-〉priority,block->cputime,block—〉alltime,block->startblock,block—>blocktime,block->state); } printf(\"\\n”); printf(”============================================================================\\n\");
/*显示状态*/ }
/*改变阻塞进程的有关参数*/
if(block!=NULL) //如果有阻塞进程 { block-〉blocktime—=1; //被阻塞的时间减1 if(block—>blocktime==0) //如果被阻塞的时间到了 {
}
}
}
strcpy(block->state,\"r\"); //状态转就绪 head=InsertQueue(head,block); //阻塞转就绪 block=NULL;
}
/*改变阻塞进程的有关参数*/ getchar();
5。运行结果
输入5个进程,分别是0—4进程,运行结果可以看到第一次运行进程1,优先数为38。 第二次运行的进程是进程1,优先数为35, cpu时间占用为1,进程所需时间为2, 同时下一个进程(进程1)的优先数+1。
第三次运行进程2,优先数32,cpu占用时间将+1,所需时间将-1. 同时下一个进程(进程1)优先数+1,.
第四次运行进程1,优先数33,cpu占用时间2+1,所需时间将—1。 同时下一个进程(进程3)优先数+1,
第四次运行进程1完毕,所需时间为0。进程1运行完毕。
第五次运行进程3,优先数33,cpu占用时间0将+1,所需时间3将-1. 同时下一个进程(进程2)优先数+1。
第六次运行进程2,优先数31将—3,cpu占用时间1将+1,所需时间5将-1。 同时下一个进程(进程3)优先数+1。
第七次运行进程3,优先数31将-3,cpu占用时间1将+1,所需时间2将-1。 同时下一个进程(进程2)优先数+1。
第八次运行进程2,优先数29将-3,cpu占用时间2将+1,所需时间4将—1。 同时下一个进程(进程3)优先数+1。
第九次运行进程3,优先数29将—3,cpu占用时间2将+1,所需时间1将-1。 同时下一个进程(进程2)优先数+1。
第九次运行完毕,进程3的所需时间为0,进程3运行完毕。
第十次运行进程2,优先数27将-3,cpu占用时间3将+1,所需时间3将—1。 同时下一个进程(进程0)优先数+1.
第十一次运行进程2,优先数24将—3,cpu占用时间4将+1,所需时间2将—1。 同时下一个进程(进程0)优先数+1。
第十二次运行进程2,优先数21将-3,cpu占用时间5将+1,所需时间1将—1. 同时下一个进程(进程0)优先数+1。
第十二次运行完毕,进程2所需时间为0,进程2运行完毕。
第十三次运行进程0,优先数21将-3,cpu占用时间0将+1,所需时间3将-1。 同时下一个进程(进程4)优先数+1.
第十四次运行进程0,优先数18将-3,cpu占用时间1将+1,所需时间2将—1。 同时下一个进程(进程4)优先数+1。
第十五次运行进程4,优先数14将—3,cpu占用时间0将+1,所需时间4将-1。 同时下一个进程(进程0)优先数+1。
第十六次运行进程4,优先数11将-3,cpu占用时间1将+1,所需时间3将—1。 同时下一个进程(进程0)优先数+1。
第十七次运行进程4,优先数8将-3,cpu占用时间2将+1,所需时间2将-1。 同时下一个进程(进程0)优先数+1.
第十八次运行进程0,优先数15将—3,cpu占用时间2将+1,所需时间1将—1。 同时下一个进程(进程4)优先数+1。
第十八次运行完毕,进程0所需时间为0,进程0运行完毕。
第十九次运行进程4,优先数6将-3,cpu占用时间3将+1,所需时间1将-1。
第二十次运行进程4,优先数6将-3,cpu占用时间3将+1,所需时间1将-1。 第二十次运行完毕,进程4所需时间为0,进程4运行完毕。
所有进程运行完毕.
5。总结
本次试验感觉难度比较大,有很多生疏的指令。但在老师和同学的帮助下都解决了。 总体上还是对进程概念和进程调度过程有了一个更深的理解。在这次试验中也暴露出自己不少的缺点,希望以后试验中可以改正!
本文利用C 语言对动态优先权的进程调度算法进行了设计和模拟实现。程序可实现动态的进行各个进程相关信息的录入, 如CPUTIME、ALLTIME、STARTBLOCK、BLOCKTIME 等信息.并充分考虑了进程在执行过程中可能发生的多种情况, 更好的体现了进程的就绪态、执行态、阻塞态三者之间的关系以及相互的转换。程序的运行过程清晰的体现了动态优先权的调度算法的执行过程, 有利于加深对算法的理解和掌握。由于抢占式调度算法与硬件密切相关, 由软件实现非常困难, 所以本程序实现的是非抢占式的动态优先权进程调度算法。抢占式的动态优先权进程调度算法的模拟实现有待于进一步研究
6、思考题
(1)在实际的调度中,除了按调度算法选择下一个执行的进程外,还应处理哪些工作?
答:1.记录系统中所有进程的执行情况
作为进程调度的准备,进程管理模块必须将系统中各个进程的执行特征记录在各个进程的PCB表中。 2.进行进程上下文交换
一个进程的上下文包括进程的状态,有关变量和数据结构的值。机器寄存器的值和PCB以及有关程序,数据等。