实验三 进程调度模拟程序
实验三 进程调度模拟程序
网络工程专业 姓名:蔡利聪 学号:201306114117
一、目的和要求
1. 实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
2.实验要求
设计一个有 N个进程并发执行的进程调度模拟程序。
进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。
(1). 每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。
(2). 进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。
(3). 每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。
(4). 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
(5). 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。
(6). 每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。
(7). 重复以上过程,直到所要进程都完成为止。
二、实验内容
编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对N(N不小于5)个进程进行调度。
三、实验方法、步骤及结果测试
1. 源程序名:动态优先数简化.cpp,可执行程序名:动态优先数简化.exe
2. 原理分析
(1)“最高优先级优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定规则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1,并且进程等待的时间超过某一时限(2个时间片时间)时增加其优先数等。
(2)定义进程控制块的结构体和程序工作时间的结构体,pcb可以包含以下信息:进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。
(3)通过构造进程输入input(),进程运行结果输出output(),disp(),以及使整个程序正常运行的函数块等,通过主函数调用方法函数的想法来实现进程调度模拟。
(4)在对进程控制块的访问和调用通过链表指针的形式,在进程控制块输入后,会显示输入的内容,并把每一个作业运行的状态都能在程序中体现出来。
3. 主要程序段及其解释:
1 #include<stdio.h> 2 #include <stdlib.h> 3 #include <conio.h> 4 #define getpch(type) (type*)malloc(sizeof(type)) 5 #define NULL 0 6 struct pcb { /* 定义进程控制块PCB */ 7 char name[10]; 8 char state; 9 int super; 10 int ntime; 11 int rtime; 12 struct pcb* link; 13 }*ready=NULL,*p; 14 typedef struct pcb PCB; 15 16 void sort() /* 建立对进程进行优先级排列函数*/ 17 { 18 PCB *first, *second; 19 int insert=0; 20 if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/ 21 { 22 p->link=ready; 23 ready=p; 24 } 25 else /* 进程比较优先级,插入适当的位置中*/ 26 { 27 first=ready; 28 second=first->link; 29 while(second!=NULL) 30 { 31 if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/ 32 { /*插入到当前进程前面*/ 33 p->link=second; 34 first->link=p; 35 second=NULL; 36 insert=1; 37 } 38 else /* 插入进程优先数最低,则插入到队尾*/ 39 { 40 first=first->link; 41 second=second->link; 42 } 43 } 44 } 45 } 46 void input() /* 建立进程控制块函数*/ 47 { 48 int i,num; 49 //clrscr(); /*清屏*/ 50 printf("\n 请输入进程个数?");//号 51 scanf("%d",&num); 52 for(i=0;i<num;i++) 53 { 54 printf("\n 进程号No.%d:\n",i); 55 p=getpch(PCB); 56 printf("\n 输入进程名:"); 57 scanf("%s",p->name); 58 printf("\n 输入进程优先数:"); 59 scanf("%d",&p->super); 60 printf("\n 输入进程运行时间:"); 61 scanf("%d",&p->ntime); 62 printf("\n"); 63 p->rtime=0;p->state='w'; 64 p->link=NULL; 65 sort(); /* 调用sort函数*/ 66 } 67 } 68 int space() 69 { 70 int l=0; PCB* pr=ready; 71 while(pr!=NULL) 72 { 73 l++; 74 pr=pr->link; 75 } 76 return(l); 77 } 78 void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/ 79 { 80 printf("\n 进程名\t状态 \t优先级 \t所需时间 \t运行时间 \n"); 81 printf("%s\t",pr->name); 82 printf(" %c\t",pr->state); 83 printf(" %d\t",pr->super); 84 printf(" %d\t",pr->ntime); 85 printf(" %d\t",pr->rtime); 86 printf("\n"); 87 } 88 void check() /* 建立进程查看函数 */ 89 { 90 PCB* pr; 91 printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/ 92 disp(p); 93 pr=ready; 94 printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/ 95 while(pr!=NULL) 96 { 97 disp(pr); 98 pr=pr->link; 99 } 100 } 101 void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/ 102 { 103 printf("\n 进程 [%s] 已完成.\n",p->name); 104 free(p); 105 } 106 void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态)*/ 107 { 108 (p->rtime)++; 109 if(p->rtime==p->ntime) 110 destroy(); /* 调用destroy函数*/ 111 else 112 { 113 (p->super)--; 114 p->state='w'; 115 sort(); /*调用sort函数*/ 116 } 117 } 118 int main() /*主函数*/ 119 { 120 int len,h=0; 121 char ch; 122 input(); 123 len=space(); 124 while((len!=0)&&(ready!=NULL)) 125 { 126 ch=getchar(); 127 h++; 128 printf("\n The execute number:%d \n",h); 129 p=ready; 130 ready=p->link; 131 p->link=NULL; 132 p->state='R'; 133 check(); 134 running(); 135 printf("\n 按任一键继续......"); 136 ch=getchar(); 137 } 138 printf("\n\n 进程已经完成.\n"); 139 ch=getchar(); 140 }
4. 运行结果
以上图所示,当输入3个进程控制块的的信息后,进程执行结果符合根据计算的结果,表明此程序达到预期效果。
四、实验总结
(1)本次实验是对作业调度程序的补充,本次实验需要对每个进程的执行过程的先后顺序的结果进行显示,所以需要考虑每个进程的优先级,即要先进行排序,然后才能执行进程的调度。
(2)通过本次实验,我觉得关于数据结构的算法和语法的基础知识很重要,特别是编写C语言程序时,涉及到一些复杂的程序,都会用到这些知识,由于数据结构基础知识学得不扎实,所以写代码遇到很多困难。虽然会定义结构体比较熟练,但是对于在程序中调用结构体就不太理解,导致多次出错,并通过查阅相关资料,然后不断修改,才把相关的实验基础要求完成。另外,写程序需要很好的思维习惯,并且要善于转化计算机操作与实际情况,才能把代码理解透,往后需要多多练习,形成自己的编程习惯和思维习惯。