第三章
一、目的和要求
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 <string.h> 4 #include <malloc.h> 5 #include <windows.h> 6 #define NUM 3 7 struct pcb 8 { 9 char name[5];//进程名 10 int value;//优先数 11 int m_time;//需要运行时间 12 int r_time;//已运行时间 13 char condition[100];//状态 14 struct pcb *next; 15 }; 16 struct pcb PCB[NUM],center; 17 struct pcb *headc; 18 int count = NUM; 19 void Initialize()/*初始化*/ 20 { 21 int i; 22 for(i=0;i<NUM;i++) 23 { 24 printf("请输入第%d个进程名:\n",i+1); 25 scanf("%s",&PCB[i].name); 26 printf("请输入第%d个进程的需要运行时间:\n",i+1); 27 scanf("%d",&PCB[i].m_time); 28 printf("请输入第%d个进程的优先数:\n",i+1); 29 scanf("%d",&PCB[i].value); 30 PCB[i].r_time=0; 31 strcpy(PCB[i].condition,"Ready"); 32 } 33 } 34 void valueChange(struct pcb *p) 35 { 36 int i = 0; 37 while(p!=NULL) 38 { 39 PCB[i] = *p; 40 p=p->next; 41 i++; 42 } 43 count = i; 44 } 45 struct pcb* Sort()/*按优先级排序(高到低)*/ 46 { 47 struct pcb *head,*q,*p1; 48 int i,j; 49 for(i=0;i<count;i++) 50 { 51 for(j=i+1;j<count;j++) 52 { 53 if(PCB[i].value<PCB[j].value) 54 { 55 center=PCB[i]; 56 PCB[i]=PCB[j]; 57 PCB[j]=center; 58 } 59 } 60 } 61 head=(struct pcb*)malloc(sizeof(struct pcb)); 62 p1=head; 63 for(i=0;i<count;i++) 64 { 65 q=(struct pcb*)malloc(sizeof(struct pcb)); 66 strcpy(q->name,PCB[i].name); 67 strcpy(q->condition,PCB[i].condition); 68 q->m_time=PCB[i].m_time; 69 q->r_time=PCB[i].r_time; 70 q->value=PCB[i].value; 71 q->next=NULL; 72 p1->next=q; 73 p1=q; 74 } 75 return head; 76 //p=head->next; 77 } 78 void PrintReady() 79 { 80 struct pcb* p; 81 p=headc->next; 82 if(p!=NULL) 83 { 84 printf("就绪队列信息:\n "); 85 printf("进程名\t优先数\t已运行时间\t还需运行时间\t进程状态\n"); 86 while(p!=NULL) 87 { 88 printf("%s\t%d\t%d\t\t%d \t\t%s\n",p->name,p->value,p->r_time,p->m_time,p->condition); 89 p=p->next; 90 } 91 } 92 } 93 94 95 int Rule() 96 { 97 struct pcb* p; 98 p=headc->next; 99 while(1) 100 { 101 if(p->r_time==p->m_time) 102 { 103 strcpy(p->condition,"Run"); 104 printf("正在运行的进程为:%s\n",p->name); 105 printf("进程名\t优先数\t已运行时间\t还需运行时间\t进程状态\n"); 106 printf("%s\t%d\t%d\t\t%d \t\t%s\n",p->name,p->value,p->r_time,p->m_time,p->condition); 107 strcpy(p->condition,"Finish"); 108 p=p->next; 109 if(p==NULL) 110 { 111 printf("所有进程结束!\n"); 112 return 0; 113 } 114 } 115 else 116 { 117 printf("正在运行的进程为:%s\n",p->name); 118 // printf("正在运行的进程的状态为:\n"); 119 strcpy(p->condition,"Run"); 120 printf("进程名\t优先数\t已运行时间\t还需运行时间\t进程状态\n"); 121 printf("%s\t%d\t%d\t\t%d \t\t%s\n",p->name,p->value,p->r_time,p->m_time,p->condition); 122 Sleep(2000); 123 if(p->next==NULL) 124 { 125 while(1) 126 { 127 p->value--; 128 p->r_time++; 129 if(p->r_time!=p->m_time+1) 130 { 131 strcpy(p->condition,"Run"); 132 printf("正在运行的进程为:%s\n",p->name); 133 printf("进程名\t优先数\t已运行时间\t还需运行时间\t进程状态\n"); 134 printf("%s\t%d\t%d\t\t%d \t\t%s\n",p->name,p->value,p->r_time,p->m_time,p->condition); 135 Sleep(2000); 136 } 137 else 138 { 139 printf("所有进程结束!\n"); 140 return 0; 141 } 142 143 144 } 145 } 146 else if(p->value<p->next->value&&p->next!=NULL) 147 { 148 valueChange(p); 149 p = Sort()->next; 150 } 151 } 152 p->value--; 153 p->r_time++; 154 } 155 return 0; 156 } 157 void main() 158 { 159 Initialize(); 160 // p2=(struct pcb *)malloc(sizeof(struct pcb)); 161 headc = Sort(); 162 PrintReady(); 163 Rule(); 164 }
四、实验总结
这个实验是对作业调度程序的补充,实验过程中需要对每个进程的执行过程的先后顺序的结果进行显示,需要考虑每个进程的优先级,即先进行排序,然后才能执行进程的调度。