实验目的

1)加深对进程概念的理解。
2)深入了解进程控制块和进程状态之间的转换。
3)掌握进程调度算法。

实验预备知识

1)进程的状态




2)进程的结构——PCB


进程都是由一系列操作(动作)所组成,通过这些操作来完成其任务。因此,不同的进程,其内部操作也不相同。在操作系统中,描述一个进程除了需要程序和私有数据之外,最主要的是需要一个与动态过程相联系的数据结构,该数据结构用来描述进程的外部特性(名字、状态等)以及与其它进程的联系(通信关系)等信息,该数据结构称为进程控制块(PCB,Process
Control Block)。


进程控制块PCB与进程一一对应,PCB中记录了系统所需的全部信息、用于描述进程情况所需的全部信息和控制进程运行所需的全部信息。因此,系统可以通过进程的PCB来对进程进行管理。

实验步骤

1)设计一个有 N个进程共行的进程调度程序。

2)进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)。每个进程有一个进程控制块(
PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪
W(Wait)、运行R(Run)、或阻塞F(Finish)三种状态之一。就绪进程获得
CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。如果运行一个时间片后,进程的已占用
CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的
PCB,以便进行检查。  

3)重复以上过程,直到所要进程都完成为止。

调度算法的流程图如下 :




实验结论

1)给出实验源程序(附有详细注释)

2)程序运行截图
#include <stdio.h> #include <stdlib.h> typedef struct pcb { int name; // 进程的名称
char state;// 进程的状态 int arrivetime; //进程的到达时间 int runtime;// 进程的执行时间 int
cputime;//cpu占用的时间 int count;//优先数 struct pcb *next; }pcb; pcb *head = NULL; //
正常对列 pcb *head1 = NULL; // 未到达的对列 int n = 0;// 进程的数量 //创建头指针 void createhead()
{ pcb *p = (pcb*)malloc(sizeof(pcb));// 创建头指针 head = p; pcb *q =
(pcb*)malloc(sizeof(pcb));// 创建头指针 head1 = q; } void sort()// 按照优先数进行排序 { pcb*
t = head; pcb *q,*p,*r; int max; while(t->next != NULL) { p = t->next; r =
t->next; max = r->count; while(r!= NULL) { if(r->count > max) { max = r->count;
p = r; } r = r->next; }// p指向count最大的那一个数 q = t; while (q->next != p) q =
q->next; if(t->next != p) { q->next = p->next; p->next = t->next; t->next = p;
}// 插入进行排序按照优先数 t = t->next; } } bool create() //创建pcb操作 { createhead(); pcb *p
= head; pcb *q = head1; printf("请输入进程数目:"); scanf("%d",&n); pcb *temp; for(int
i=1;i<=n;i++ )//尾插法建立就绪队列 { temp = (pcb*)malloc(sizeof(pcb)); if(!temp) return
false; printf("请输入进程%d的要求运行时间,进程优先数,到达时间:",i); scanf("%d %d
%d",&(temp->runtime),&(temp->count),&(temp->arrivetime)); temp->cputime = 0;
temp->name=i; temp->next = NULL; temp->state='W'; if(temp->arrivetime!=0) //
对到达时间进行判断 { q->next = temp; q = temp; } else { p->next = temp; p = temp; } }
sort(); // 排序 return true; } void destory(pcb *rp)// 撤销操作 {
printf("****************进程%d已完成****************\n",rp->name); pcb *q =
rp->next; head->next = q; free(rp); } void display(pcb *rp) // 展示当前的信息 {
printf("进程名字:%d",rp->name); printf("\n进程优先级:%d",rp->count);
printf("\n进程所占时间片:%d",rp->runtime); printf("\n进程已运行时间:%d",rp->cputime);
printf("\n进程当前状态:%c",rp->state);
printf("\n=====================================\n"); } void arrivetime()//
对于到达时间-1的操作 { pcb *q = head1->next; pcb *r,*t; while(q!=NULL) // 判断到达时间是否为0
此时是否到达 { q->arrivetime--; if(q->arrivetime==0) { t = head1; while(t->next!=q) t
= t->next; t->next = q->next; r = head->next; q->next = r; head->next = q; } q
= q->next; } } void runpcb(pcb *rp) { rp->cputime++; //修改cpu占用的时间 arrivetime();
printf("----------正在运行的进程----------\n"); // 输出正在运行的队列 display(rp);
if(rp->cputime==rp->runtime) { destory(rp); } else { rp->count--; rp->state =
'W'; } pcb *p = head; if(head->next==NULL&&head1->next==NULL) return;
printf("----------处于就绪对列的进程----------\n"); // 输出就绪的队列 while(p->next!=NULL) {
display(p->next); p = p->next; } pcb *q = head1; while(q->next!=NULL) {
display(q->next); q = q->next; } sort(); } int main() { create();// 创造进程 pcb *
p; while(head->next!=NULL || head1->next!=NULL) // 判断两个对列的进程是否都走完 {
if(head->next!=NULL) { p= head->next; p->state='R'; runpcb(p); } else {
arrivetime(); } } return 0; }