目标:
• 1. 复习CPU调度的四种基本调度算法
• 2.复习平均等待时间以及平均周转时间
• 3. 通过编程模拟CPU调度的过程,深化对CPU的四种基本调度算法的理解
基本调度算法
• FCFS(先进先出算法)
• SJF(短作业优先算法)
• 优先级调度算法
• RR(时间片轮转调度算法)
等待时间和周转时间
• 等待时间
– 进程在等待队列中的时间总和
• 周转时间
– 进程从提交到进程完成的时间总和
实验内容
• 分别使用FCFS、 SJF(非抢占)、优先级调度(非抢占)、 RR四种调度算法来模拟CPU调度的过程。(Linux、 Windows下皆可,语言不限)
• 输入:存储需要调度的作业信息的job.txt文档
• 输出:每个作业的编号、作业开始执行时间、作业结束时间以及该调度算法的平均等待时间、平均周转时间
• 选作: SJF(抢占)、优先级调度(抢占)
说明:
• 1. job.txt说明:
第一行:作业数 轮转片大小
第二行以后:作业编号 到达时间 执行时间 优先级
• 2. 输出说明:
FCFS: 作业编号 开始执行时间 结束时间
…… …… ……
Average waiting time: 平均等待时间
Time for Average Turnaround : 平均周转时间
SJF(非抢占): 作业编号 开始执行时间 结束时间
…… …… ……
Average waiting time: 平均等待时间
Time for Average Turnaround : 平均周转时间
……
代码:
#include<stdio.h> #include<queue> #include<iostream> using namespace std; int pnum; int ptime; int index[255]; int time1[255]; int use_time[255]; int level[255]; void FCFS() { int wait_time[255]; int turn_time[255]; int nowtime=0; printf("FCFS: \n作业编号 开始执行时间 结束时间 \n"); for(int i=0;i<pnum;i++) { printf("%d ",index[i]); /*开始运行*/ if(time1[i]>=nowtime) //到达时间大于现在时间 ,作业晚到wait { printf("%d ",time1[i]); nowtime=time1[i]; wait_time[i]=0; //作业没有等待 } else//到达时间小于现在时间 ,作业早到 { printf("%d ",nowtime); wait_time[i]=nowtime-time1[i]; } /*结束时间*/ printf("%d ",nowtime+use_time[i]); nowtime+=use_time[i]; turn_time[i]=nowtime-time1[i]; //结束时间-到达时间 printf("\n"); } float all_wait_time=0; float all_turn_time=0; for(int i=0;i<pnum;i++) { all_wait_time+=wait_time[i]; all_turn_time+=turn_time[i]; } printf("Average waiting time:%f\n",all_wait_time/pnum); printf("Time for Average Turnaround : %f\n",all_turn_time/pnum); } int flag[255]; //find_min 表示以读取 int check()//检查是否完成 完成返回0 { int end=0; for(int i=0;i<pnum;i++) if(flag[i]==0) end=1; return end; } int find_min(int have_in) { int next=999; int min=999; for(int i=0;i<have_in;i++) { if(flag[i]==0 && use_time[i]<min) { min=use_time[i]; next=i; } } return next; } void SJF() { int have_in=1; int wait_time[255]; int turn_time[255]; int nowtime=0; float all_wait_time=0; float all_turn_time=0; for(int i=0;i<255;i++) flag[i]=0; printf("SJF(非抢占):\n 作业编号 开始执行时间 结束时间\n"); int i=0; while(1) { if(have_in==0) //第一个 { printf("%d %d %d\n",index[0],time1[0],use_time[0]); nowtime=time1[i]+use_time[0]; wait_time[0]=0; turn_time[0]=use_time[0]; flag[0]=1; //已经运行 } for(int j=have_in;j<pnum;j++) //查找运行一个作业期间进入队列的其他队列 { if(nowtime>=time1[j]&&flag[j]==0) //目前时间>=到达时间 作业到达 have_in++; } int next=find_min(have_in); if(check()==0) //结束判断 break; if(next==999)//目前没有新的作业进入 { next=have_in; //直接取下一个 have_in++; nowtime=time1[next]; //现在时间跳到下一个进程进入时间 } printf("%d ",index[next]); printf("%d ",nowtime); printf("%d \n",nowtime+use_time[next]); wait_time[next]=nowtime-time1[next]; nowtime+=use_time[next]; turn_time[next]=nowtime-time1[next]; flag[next]=1; } for(int i=0;i<pnum;i++) { all_wait_time+=wait_time[i]; all_turn_time+=turn_time[i]; } printf("Average waiting time:%f\n",all_wait_time/pnum); printf("Time for Average Turnaround : %f\n",all_turn_time/pnum); } int find_max(int have_in) { int next=999; int min=999; for(int i=0;i<have_in;i++) { if(flag[i]==0 && level[i]<min) { min=level[i]; next=i; } } return next; } void Power() { int have_in=1; int wait_time[255]; int turn_time[255]; int nowtime=0; float all_wait_time=0; float all_turn_time=0; for(int i=0;i<255;i++) flag[i]=0; printf("优先级调度(非抢占):\n 作业编号 开始执行时间 结束时间\n"); while(1) { if(have_in==0) //第一个 { printf("%d ",index[0]); printf("%d ",time1[0]); printf("%d \n",use_time[0]); nowtime=time1[0]+use_time[0]; wait_time[0]=0; turn_time[0]=use_time[0]; flag[0]=1; //已经运行 } for(int j=have_in;j<pnum;j++) //查找运行一个作业期间进入队列的其他队列 { if(nowtime>=time1[j]&&flag[j]==0) //目前时间>=到达时间 作业到达 have_in++; } int next=find_max(have_in); if(check()==0) //结束判断 break; if(next==999)//目前没有新的作业进入 { next=have_in; //直接取下一个 have_in++; nowtime=time1[next]; //现在时间跳到下一个进程进入时间 } printf("%d ",index[next]); printf("%d ",nowtime); printf("%d \n",nowtime+use_time[next]); wait_time[next]=nowtime-time1[next]; nowtime+=use_time[next]; turn_time[next]=nowtime-time1[next]; flag[next]=1; } for(int i=0;i<pnum;i++) { all_wait_time+=wait_time[i]; all_turn_time+=turn_time[i]; } printf("Average waiting time:%f\n",all_wait_time/pnum); printf("Time for Average Turnaround : %f\n",all_turn_time/pnum); } void RR() { queue<int> p; //创建队列 p.push(0); int nowtime=time1[0];//调整现在时间 int have_use_time[255];//已经工作时间 int start_time[255];//开始工作时间 int end_time[255];//结束工作时间 float wait_time[255]; float turn_time[255]; int have_in=1; //已经进入 for(int i=0;i<255;i++) { flag[i]=0; have_use_time[i]=0; start_time[i]=0; end_time[i]=0; wait_time[i]=0; turn_time[i]=0; } while(check()==1) { /*从队列中取出一个作业*/ int i=p.front(); p.pop(); if(have_use_time[i]==0)//运行时间为零,第一次进入 start_time[i]=nowtime; if(have_use_time[i]+ptime>=use_time[i]) { nowtime+=use_time[i]-have_use_time[i]; flag[i]=1; have_use_time[i]=use_time[i]; end_time[i]=nowtime; } else { nowtime+=ptime; have_use_time[i]+=ptime; } for(int j=have_in;j<pnum;j++) { if(nowtime>=time1[j]&&flag[j]==0)//已经进入 { have_in++; p.push(j); } } if(have_use_time[i]!=use_time[i]) p.push(i); if(p.empty() && check())//队列空 但未完成 { nowtime=time1[have_in]; p.push(have_in); have_in++; } } float all_wait_time=0; float all_turn_time=0; for(int i=0;i<pnum;i++) { wait_time[i]=end_time[i]-time1[i]-use_time[i];//等待时间=结束时间-到达时间-工作时间 turn_time[i]=end_time[i]-time1[i]; printf("%d %d %d\n",index[i],start_time[i],end_time[i]); all_wait_time+=wait_time[i]; all_turn_time+=turn_time[i]; } printf("Average waiting time:%f\n",all_wait_time/pnum); printf("Time for Average Turnaround : %f\n",all_turn_time/pnum); } int main() { FILE *fp=NULL; fp=fopen("job.txt","r"); fscanf(fp,"%d",&pnum);//作业量 fscanf(fp,"%d",&ptime);//时间片 for(int i=0;i<pnum;i++) { fscanf(fp,"%d",&index[i]);//标号 fscanf(fp,"%d",&time1[i]);//到达时间 fscanf(fp,"%d",&use_time[i]);//所需时间 fscanf(fp,"%d",&level[i]);//优先级 } fclose(fp); printf("%d %d\n",pnum,ptime); for(int i=0;i<pnum;i++) { printf("%d %d %d %d\n",index[i],time1[i],use_time[i],level[i]); } FCFS(); SJF(); Power(); RR(); }