一、实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验要求
设计一个有 N个进程并发执行的进程调度模拟程序。
1.模拟进程数据的生成,允许用户选择输入每个进程所需运行时间,进程的运行时间以时间片为单位。
2. 模拟调度程序的功能
2.1 按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法。
FCFS
SJ
HRRN
RR
2.2 显示每种算法下各进程的调度执行顺序。
2.3计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
三、实验说明
1) 先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间。
4) 时间片轮转(RR)调度算法:调度程序每次把CPU分配给就绪队列首进程使用一个时间片,就绪队列中的每个进程轮流地运行一个时间片。当这个时间片结束时,强迫一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度。
四、程序代码:
#include<stdio.h> #define time int #define max 24 typedef struct queue{ char name; int intime; int needtime; int runningtime; float priority; int waitingtime; char state; int starttime; int finishtime; float turntime; float turnnumber; }PCB; int n; int ptime; PCB pcb[max]; void addprocess(int n){ int i; for(i=0;i<n;i++){ printf(" 请输入进程名:"); scanf("%s", &pcb[i].name); printf(" 请输入进程的优先级:"); scanf("%f", &pcb[i].priority); printf(" 请输入进程的所需时间:"); scanf("%d", &pcb[i].needtime); pcb[i].intime=i; pcb[i].state='W';//将进程的状态初始化为等待态 pcb[i].runningtime=0; } } void sort(){ int i,j; PCB temp; //通过排序将优先级最高的进程排到最前面 for (i=0;i<n-1;i++) { for (j=n-2;j>=i;j--) { if (pcb[j+1].priority>pcb[j].priority) { temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; } } } if (pcb[0].state!='F') { pcb[0].state='R'; //将优先级最高的状态置为运行 } } void Print(){ int i; printf(" 进程名 优先级 到达时间 需要时间 已用时间 进程状态 "); for (i=0;i<n;i++) { printf("%7s%12f%10d%10d%10d%10c ",&pcb[i].name,pcb[i].priority, pcb[i].intime,pcb[i].needtime,pcb[i].runningtime,pcb[i].state); } } void Print1(){ int i; printf(" 进程名 完成时间 开始的时间 周转时间 周转系数 "); for (i=0;i<n;i++) { printf("%7s%10d%9d%20f%20f% ",&pcb[i].name,pcb[i].finishtime,pcb[i].starttime, pcb[i].turntime,pcb[i].turnnumber); } } void RRattemper() //调度 { int i=0,j=0; do{ if(i==n){ i=0; } if ((pcb[i].needtime-pcb[i].runningtime)>ptime) { pcb[i].runningtime=pcb[i].runningtime+ptime; //已用时间加时间片 pcb[i].state='W'; i++; } else { if(i==n){ i=0; } pcb[i].runningtime=pcb[i].needtime;//已用时间等于需要时间 pcb[i].state='F'; //完成进程,将状态置为完成 if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; i++; if(i==n){ i=0; } if(pcb[i].state=='F'){ j++; } } Print(); }while(j<n); Print1(); } void FCFSattemper() { int i=0; pcb[0].state='R'; //将最先到达的状态置为运行 do{ if(pcb[i].state=='R'){ pcb[i].runningtime=pcb[i].needtime; if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; pcb[i].state='F'; i++; pcb[i].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); } void SJattemper() { int i,j; PCB temp; //通过排序将时间最少的进程排到最前面 for (i=0;i<n-1;i++) { for (j=n-2;j>=i;j--) { if (pcb[j+1].needtime<pcb[j].needtime) { temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; } } } pcb[0].state='R'; //将时间最少的状态置为运行 i=0; do{ if(pcb[i].state=='R'){ pcb[i].runningtime=pcb[i].needtime; if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; pcb[i].state='F'; i++; pcb[i].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); } void HRRNattemper() { int i,j,k=1; PCB temp; sort(); pcb[0].runningtime=pcb[0].needtime; pcb[1].waitingtime=pcb[0].needtime; pcb[0].state='F'; for(i=1;i<n;i++){ pcb[i].runningtime=pcb[i].needtime; pcb[i].priority=1+pcb[i].waitingtime/pcb[i].runningtime; pcb[i+1].waitingtime=pcb[i].needtime+pcb[i].waitingtime; } for (i=1;i<n-1;i++) { for (j=n-2;j>=i;j--) { if (pcb[j+1].priority>pcb[j].priority) { temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; } } } for(i=1;i<n;i++){ pcb[i].runningtime=0; } pcb[1].state='R'; do{ if(pcb[k].state=='R'){ pcb[k].runningtime=pcb[k].needtime; pcb[k].runningtime=pcb[k].needtime; if(k==0){ pcb[k].waitingtime=0; }else{ pcb[k].waitingtime=pcb[k-1].needtime+pcb[k-1].waitingtime; } pcb[k].starttime=pcb[k].waitingtime; pcb[k].finishtime=pcb[k].waitingtime+pcb[k].runningtime; pcb[k].turntime=(float)pcb[k].finishtime-pcb[k].intime; pcb[k].turnnumber=(float)pcb[k].turntime/pcb[k].needtime; pcb[k].state='F'; k++; pcb[k].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); } int choose(){ int number; printf(" 选择FCFS算法的请输入1: "); printf(" 选择SJ算法的请输入2: "); printf(" 选择HRRN算法的请输入3: "); printf(" 选择RR算法的请输入4: "); printf(" 结束请输入0: "); scanf("%d",&number); return number; } main(){ int chose; n=0; printf("请输入进程数:"); scanf("%d", &n); addprocess(n); Print(); chose=choose(); do{ if(chose==1){FCFSattemper(); chose=choose();} if(chose==2){SJattemper(); chose=choose();} if(chose==3){HRRNattemper(); chose=choose();} if(chose==4){printf("请输入时间片的值:"); scanf("%d",&ptime);RRattemper(); chose=choose();} if(chose==0){break;} }while(1); }
五、程序代码的简单说明
(1)、定义一个进程控制块PCB:
typedef struct queue{ char name; int intime; int needtime; int runningtime; float priority; int waitingtime; char state; int starttime; int finishtime; float turntime; float turnnumber; }PCB;
(2)、程序的主函数:
main(){ int chose; n=0; printf("请输入进程数:"); scanf("%d", &n); addprocess(n); Print(); chose=choose(); do{ if(chose==1){FCFSattemper(); chose=choose();} if(chose==2){SJattemper(); chose=choose();} if(chose==3){HRRNattemper(); chose=choose();} if(chose==4){printf("请输入时间片的值:"); scanf("%d",&ptime);RRattemper(); chose=choose();} if(chose==0){break;} }while(1); }
(3)、输入进程的函数:
void addprocess(int n){ int i; for(i=0;i<n;i++){ printf(" 请输入进程名:"); scanf("%s", &pcb[i].name); printf(" 请输入进程的优先级:"); scanf("%f", &pcb[i].priority); printf(" 请输入进程的所需时间:"); scanf("%d", &pcb[i].needtime); pcb[i].intime=i; pcb[i].state='W';//将进程的状态初始化为等待态 pcb[i].runningtime=0; } }
(4)算法选择的函数:
int choose(){ int number; printf(" 选择FCFS算法的请输入1: "); printf(" 选择SJ算法的请输入2: "); printf(" 选择HRRN算法的请输入3: "); printf(" 选择RR算法的请输入4: "); printf(" 结束请输入0: "); scanf("%d",&number); return number; }
(5)、先来先服务(FCFS)调度算法:
void FCFSattemper() {
int i=0; pcb[0].state='R'; //将最先到达的状态置为运行 do{ if(pcb[i].state=='R'){ pcb[i].runningtime=pcb[i].needtime; if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; pcb[i].state='F'; i++; pcb[i].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); }
(6)、短作业优先 (SJF) 调度算法:
void SJattemper() { int i,j; PCB temp; //通过排序将时间最少的进程排到最前面 for (i=0;i<n-1;i++) { for (j=n-2;j>=i;j--) { if (pcb[j+1].needtime<pcb[j].needtime) { temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; } } } pcb[0].state='R'; //将时间最少的状态置为运行 i=0; do{ if(pcb[i].state=='R'){ pcb[i].runningtime=pcb[i].needtime; if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; pcb[i].state='F'; i++; pcb[i].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); }
(7)、响应比高者优先(HRRN)调度算法:
void HRRNattemper() { int i,j,k=1; PCB temp; sort(); pcb[0].runningtime=pcb[0].needtime; pcb[1].waitingtime=pcb[0].needtime; pcb[0].state='F'; for(i=1;i<n;i++){ pcb[i].runningtime=pcb[i].needtime; pcb[i].priority=1+pcb[i].waitingtime/pcb[i].runningtime; pcb[i+1].waitingtime=pcb[i].needtime+pcb[i].waitingtime; } for (i=1;i<n-1;i++) { for (j=n-2;j>=i;j--) { if (pcb[j+1].priority>pcb[j].priority) { temp=pcb[j]; pcb[j]=pcb[j+1]; pcb[j+1]=temp; } } } for(i=1;i<n;i++){ pcb[i].runningtime=0; } pcb[1].state='R'; do{ if(pcb[k].state=='R'){ pcb[k].runningtime=pcb[k].needtime; pcb[k].runningtime=pcb[k].needtime; if(k==0){ pcb[k].waitingtime=0; }else{ pcb[k].waitingtime=pcb[k-1].needtime+pcb[k-1].waitingtime; } pcb[k].starttime=pcb[k].waitingtime; pcb[k].finishtime=pcb[k].waitingtime+pcb[k].runningtime; pcb[k].turntime=(float)pcb[k].finishtime-pcb[k].intime; pcb[k].turnnumber=(float)pcb[k].turntime/pcb[k].needtime; pcb[k].state='F'; k++; pcb[k].state='R'; } }while(pcb[n].state!='F'); Print(); Print1(); }
(8)时间片轮转(RR)调度算法:
void RRattemper() //调度 {
int i=0,j=0; do{ if(i==n){ i=0; } if ((pcb[i].needtime-pcb[i].runningtime)>ptime){ pcb[i].runningtime=pcb[i].runningtime+ptime; //已用时间加时间片 pcb[i].state='W'; i++; } else { if(i==n){ i=0;
} pcb[i].runningtime=pcb[i].needtime;//已用时间等于需要时间 pcb[i].state='F'; //完成进程,将状态置为完成 if(i==0){ pcb[i].waitingtime=0; }else{ pcb[i].waitingtime=pcb[i-1].needtime+pcb[i-1].waitingtime; } pcb[i].starttime=pcb[i].waitingtime; pcb[i].finishtime=pcb[i].waitingtime+pcb[i].runningtime; pcb[i].turntime=(float)pcb[i].finishtime-pcb[i].intime; pcb[i].turnnumber=(float)pcb[i].turntime/pcb[i].needtime; i++; if(i==n){ i=0; } if(pcb[i].state=='F'){ j++; } } Print();
}while(j<n); Print1(); }
六、实验结果截图:
图1、输入进程的效果图
图2、先来先服务算法效果图
图3、短作业优先 (SJF) 调度算法效果图
图4、响应比高者优先(HRRN)调度算法效果图
图5.1、时间片轮转(RR)调度算法效果图
图5.2、时间片轮转(RR)调度算法效果图
图5.3、时间片轮转(RR)调度算法效果图
七、试验总结:
通过几次的模拟进程的调度,对进程在操作系统中调度就更加了解,认识更深刻。