实验一: 进程状态转换及PCB的模拟

2019-07-14 07:30发布

实验目的
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 #include 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已完成**************** ",rp->name); pcb *q = rp->next; head->next = q; free(rp); } void display(pcb *rp) // 展示当前的信息 { printf("进程名字:%d",rp->name); printf(" 进程优先级:%d",rp->count); printf(" 进程所占时间片:%d",rp->runtime); printf(" 进程已运行时间:%d",rp->cputime); printf(" 进程当前状态:%c",rp->state); printf(" ===================================== "); } 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("----------正在运行的进程---------- "); // 输出正在运行的队列 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("----------处于就绪对列的进程---------- "); // 输出就绪的队列 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; }