} 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(\head=CreatQueue(num); getchar(); 东北大学秦皇岛分校计算机与通信工程学院???????????????????????????????????????????????????操作系统??????????????????实验报告? temp2->next=temp1; temp1->next=temp3; } return head; 操作系统??????????????????实验报告?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->next=NULL; /*显示状态*/ printf(\ //显示执行进程 printf(\ //显示就绪进程 temp=head; while(temp!=NULL) { printf(\ temp=temp->next; } printf(\ printf(\ //显示阻塞进程 if(block!=NULL) { printf(\ } printf(\ printf(\ printf(\STARTBLOCK BLOCKTIME STATE\\n\ printf(\%d %d %d %d %d %s\\n\ temp=head; while(temp!=NULL) { printf(\%d %d %d %d %d %s\\n\ temp=temp->next; } if(block!=NULL) { printf(\%d %d %d %d %d %s\ } 东北大学秦皇岛分校计算机与通信工程学院??????????????????????????????????????????????????? 操作系统??????????????????实验报告? printf(\printf(\ /*显示状态*/ /*改变优先数*/ run->priority-=3; //执行进程的优先数减3 temp=head; 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; //执行完一个时间片后,开始阻塞的时间减1 if(run->startblock==0) //如果阻塞的时间到了 { block=run; //执行转阻塞 strcpy(block->state,\ //状态转阻塞 alltime--; printf(\ continue; } } strcpy(run->state,\ //状态转就绪 head=InsertQueue(head,run); //执行转就绪 run=NULL; } /*改变执行进程的有关参数*/ alltime--; } else { /*显示状态*/ printf(\ //显示执行进程 printf(\ //显示就绪进程 printf(\ //显示阻塞进程 if(block!=NULL) { printf(\ } 东北大学秦皇岛分校计算机与通信工程学院??????????????????????????????????????????????????? 操作系统??????????????????实验报告? printf(\ printf(\ printf(\STARTBLOCK BLOCKTIME STATE\\n\ if(block!=NULL) { printf(\%d %d %d %d %d %s\ } printf(\ printf(\ /*显示状态*/ } /*改变阻塞进程的有关参数*/ if(block!=NULL) //如果有阻塞进程 { block->blocktime-=1; //被阻塞的时间减1 if(block->blocktime==0) //如果被阻塞的时间到了 { strcpy(block->state,\ //状态转就绪 head=InsertQueue(head,block); //阻塞转就绪 block=NULL; } } /*改变阻塞进程的有关参数*/ getchar(); } } 4思考 (1)实际进程调度中,除了按调度算法选择下一个执行的进程外,还需要处理哪些工作? 记录系统中所有进程的执行情况 ,作为进程调度的准备,进程管理模块必须将系统中各个进程的执行特征记录在各个进程的PCB表中。 进行进程上下文切换 ,一个进程的上下文包括进程的状态,有关变量和数据结构的值。机器寄存器的值和PCB以及有关程序,数据等。 (2)为什么对进程的优先数可按上述原则进行修改? 最高优先权调度算法仅有利于优先权高的进程,当不断有优先权高的进程需调度时,优先权低的进程将很难得到处理机的处理,所以进程在就绪队列中每呆一个时间片,优先数就增加1,使优先权低的进程不总是忙等,优先权随着时间的递增逐步增大。 东北大学秦皇岛分校计算机与通信工程学院???????????????????????????????????????????????????