编写并调试一个多道程序系统的作业调度模拟程序。
作业调度算法:采用基于优先级的作业调度。
本程序中,我设定CPU最大可运行资源数为10,时间片为0.5,如果输入的作业(单个)占用CPU时间大于10,程序终止,无法调度。
测试样例:
作业名 提交时间 CPU时间 IO时间 优先级
1 5 2 1 3
2 2 5 4 4
3 2 4 2 1
按照优先级排序:2,1,3
原理:从时间 2 开始,作业2运行0.5后交给作业1,以此类推,直到作业1先完成,此时轮转了3次 + 1 = 3*1.5 + 1 = 5.5,作业1完成时间为 5.5 + 2 + 1 = 8.5,而它不占用CPU的时间是7.5(IO不占用)。
ex:作业1完成时间 8.5,周转时间 8.5 - 5 = 3.5,带权周转时间 3.5 / 2 = 1.75。
作业 3 完成时间 = 2 + 3*1.5(作业1在,每轮1.5)+ 1.5(作业1收尾这一轮) + 4*1(只剩2个,每轮1) + 2 = 14
作业2完成时间 = 2 + 3*1.5 + 1.5(作业1收尾这一轮) + 4*1(作业3在,每轮1) + 2*0.5 + 4 = 17
代码:
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; struct Box { string ID; //作业号 int priority; //优先级 double begin_time; //提交时间 double rtime; //已经运行时间 double turnaround_time; //周转时间 double cpu_service_time; //占用CPU的时间 double io_time; //用于I/O的时间 double finish_time; //完成时间 double Wturnaround_time; //带权周转时间 Box& operator = (const Box& p2) //重载 = 运算符,方便排序 { this->priority = p2.priority; this->begin_time = p2.begin_time; this->rtime = p2.rtime; this->finish_time = p2.finish_time; this->cpu_service_time = p2.cpu_service_time; this->io_time = p2.io_time; this->ID = p2.ID; this->turnaround_time = p2.turnaround_time; this->Wturnaround_time = p2.Wturnaround_time; return *this; } }; typedef struct { Box data[100]; } JCB; const double CPU = 10.0; const double index = 0.5; JCB jcb,jcb_1; int n,number; void init() //初始化作业块 { cout<<"please input the number of the job:"; cin>>n; number = n; for(int i = 0; i<n; i++) { cout<<"process ID:"; cin>>jcb.data[i].ID; cout<<jcb.data[i].ID<<"'s begin time:"; cin>>jcb.data[i].begin_time; cout<<jcb.data[i].ID<<"'s cpu_service time:"; cin>>jcb.data[i].cpu_service_time; cout<<jcb.data[i].ID<<"'s I/O time:"; cin>>jcb.data[i].io_time; cout<<jcb.data[i].ID<<"'s priority:"; cin>>jcb.data[i].priority; jcb.data[i].rtime = 0; } for(int i = 0; i<n-1; i++) //按照优先级从大到小排序 { for(int j = i+1; j<n; j++) { if(jcb.data[i].priority < jcb.data[j].priority) swap(jcb.data[i],jcb.data[j]); } } for(int i = 0; i<n-1; i++) { for(int j = i+1; j<n; j++) { if(jcb.data[i].begin_time == jcb.data[j].begin_time && jcb.data[i].ID > jcb.data[j].ID) swap(jcb.data[i],jcb.data[j]); } } } void youxianji() //优先级 { int j = 0; double running = CPU; double bt = jcb.data[0].begin_time; double gtt = 0; double gwtt = 0; double real_begin; double record = jcb.data[0].begin_time; int num = n-1; cout<<"ID "<<"leave time "<<"begin time "<<"turnaround time "<<"finish time "<<"wighted turnaround time"<<endl; while(1) { if(jcb.data[j].cpu_service_time > CPU) { cout<<"over running range!!!"<<endl; exit(0); } jcb.data[j].rtime += index; record += index; if(running >= 0) { if (jcb.data[j].rtime >= jcb.data[j].cpu_service_time) { real_begin = bt; jcb.data[j].finish_time = record + jcb.data[j].io_time; jcb.data[j].turnaround_time = jcb.data[j].finish_time - jcb.data[j].begin_time; jcb.data[j].Wturnaround_time = jcb.data[j].turnaround_time / jcb.data[j].rtime; cout<<jcb.data[j].ID<<" "<<real_begin<<" " <<jcb.data[j].begin_time<<" "<<jcb.data[j].turnaround_time <<" "<<jcb.data[j].finish_time<<" " <<jcb.data[j].Wturnaround_time<<endl; n--; running -= jcb.data[j].cpu_service_time; bt = record; gtt += jcb.data[j].turnaround_time; gwtt += jcb.data[j].Wturnaround_time; } else { num++; swap(jcb.data[num],jcb.data[j]); } } else { running += jcb.data[j].cpu_service_time; num++; swap(jcb.data[num],jcb.data[j]); } if(n == 0) break; j++; } cout<<" average of turnaround time:"<<gtt/number<<endl<<"average of wighted turnaround time:"<<gwtt/number<<endl; } int main() { init(); youxianji(); return 0; }