#include<iostream>
#include<fstream>
#include <algorithm>
#include <queue>
using namespace std;
int mission; //任务数
double time_piece; //时间片大小
class process
{
private:
double index; //任务编号
double exe_time; //运行时间
double arrive_time; //到达时间
double priority; //优先级
public:
double wait_time; //等待时间
double begin_time; //开始时间
double end_time; //结束时间
double remain_time; //剩余执行时间
process();
process(double index,double exe_time,double arrive_time,double priority);
const double get_index()const {return index;}
const double get_exe_time()const {return exe_time;}
const double get_arrive_time()const {return arrive_time;}
const double get_priority()const {return priority;}
friend ostream& operator << (ostream&,process&);
};
process::process()
{
index = 0;
exe_time = 0;
arrive_time = 0;
priority = 0;
remain_time = 0;
}
process::process(double index,double arrive_time,double exe_time,double priority)
{
this->index = index;
this->arrive_time = arrive_time;
this->exe_time = exe_time;
this->priority = priority;
this->remain_time = exe_time;
}
//用于找到在p[x]执行完之前到达了第几个任务
int min_exetime(process p[], int x)
{
int min=0;
double end = p[x].end_time;
for(int i=0;i<mission;i++)
{
if(p[i].get_arrive_time()<end)
min = i;
}
return min;
}
ostream& operator << (ostream& output,process& p)
{
output<<"作业编号:"<<p.get_index()<<" 开始时间:"<<p.begin_time<<" 结束时间:"<<p.end_time<<endl;
return output;
}
//重载<用于sort()函数对任务到达时间升序排列
bool operator < (const process &leftObj, const process &rightObj)
{
return (leftObj.get_arrive_time() < rightObj.get_arrive_time());
}
//用于sort()函数对任务执行时间升序排列
bool compare_exe (const process &leftObj, const process &rightObj)
{
return (leftObj.get_exe_time() < rightObj.get_exe_time());
}
//用于sort()函数对任务优先级降序排列,优先数越小优先级越高
bool compare_priority (const process &leftObj, const process &rightObj)
{
return (leftObj.get_priority() < rightObj.get_priority());
}
void FCFS(process p0[])
{
process p[mission];
for(int i=0;i<mission;i++)
{
p[i] = p0[i];
}
double sum_waiting=0,sum_turnaround=0; //平均等待和周转时间
double CPU_time = p[0].get_arrive_time();
//开始依次运行
for(int i=0;i<mission;i++)
{
//若下一个任务还未到达,CUP空闲一段时间
if(p[i].get_arrive_time() > CPU_time)
{
p[i].wait_time = 0;
CPU_time = p[i].begin_time = p[i].get_arrive_time();
}
else //执行完这个任务时下一个任务已经到达
{
p[i].begin_time = CPU_time;
p[i].wait_time = CPU_time - p[i].get_arrive_time();
}
CPU_time = p[i].end_time = CPU_time+p[i].get_exe_time();
sum_waiting += p[i].wait_time;
sum_turnaround += (p[i].end_time-p[i].get_arrive_time());
}
//输出结果
cout<<"FCFS: "<<endl;
for(int i=0;i<mission;i++)
cout<<p[i]<<endl;
cout<<"Average waiting time: "<<sum_waiting/mission<<endl;
cout<<"Time for Average Turnaround: "<<sum_turnaround/mission<<endl;
cout<<""<<endl;
}
void SJF(process p[])
{
double sum_waiting=0,sum_turnaround=0; //平均等待和周转时间
double CPU_time = p[0].get_arrive_time();
int min=0; //标志已到达第几个任务
process temp[mission];
for(int i=0;i<mission;i++)
{
temp[i]=p[i];
}
for(int i=0;i<mission;i++)
{
if(temp[i].get_arrive_time() > CPU_time)
{
temp[i].wait_time = 0;
CPU_time = temp[i].begin_time = temp[i].get_arrive_time();
}
else
{
temp[i].begin_time = CPU_time;
temp[i].wait_time = CPU_time - temp[i].get_arrive_time();
}
CPU_time = temp[i].end_time = CPU_time+temp[i].get_exe_time();
sum_waiting += temp[i].wait_time;
sum_turnaround += (temp[i].end_time-temp[i].get_arrive_time());
min = min_exetime(temp,i); //已到达第min个任务
if(min > i)
sort(temp+i+1, temp+min+1, compare_exe); //按执行时间升序排已到达任务(不包括执行完的)
}
cout<<"SJF: "<<endl;
for(int i=0;i<mission;i++)
cout<<temp[i]<<endl;
cout<<"Average waiting time: "<<sum_waiting/mission<<endl;
cout<<"Time for Average Turnaround: "<<sum_turnaround/mission<<endl;
cout<<""<<endl;
}
void PRO(process p[])
{
double sum_waiting=0,sum_turnaround=0; //平均等待和周转时间
double CPU_time = p[0].get_arrive_time();
int min=0; //标志已到达第几个任务
process temp[mission];
for(int i=0;i<mission;i++)
{
temp[i]=p[i];
}
for(int i=0;i<mission;i++)
{
if(temp[i].get_arrive_time() > CPU_time)
{
temp[i].wait_time = 0;
CPU_time = temp[i].begin_time = temp[i].get_arrive_time();
}
else
{
temp[i].begin_time = CPU_time;
temp[i].wait_time = CPU_time - temp[i].get_arrive_time();
}
CPU_time = temp[i].end_time = CPU_time+temp[i].get_exe_time();
sum_waiting += temp[i].wait_time;
sum_turnaround += (temp[i].end_time-temp[i].get_arrive_time());
min = min_exetime(temp,i); //已到达第min个任务
if(min > i)
sort(temp+i+1, temp+min+1, compare_priority); //按优先级升序排已到达任务(不包括执行完的)
}
cout<<"PRO: "<<endl;
for(int i=0;i<mission;i++)
cout<<temp[i]<<endl;
cout<<"Average waiting time: "<<sum_waiting/mission<<endl;
cout<<"Time for Average Turnaround: "<<sum_turnaround/mission<<endl;
cout<<""<<endl;
}
void RR(process p[])
{
double sum_waiting=0,sum_turnaround=0; //平均等待和周转时间
double CPU_time = p[0].get_arrive_time();
process *pcb,*ins;
queue<process> wait;
queue<process> ready;
queue<process> inspect;
queue<process> out_put;
//所有任务先全入等待队列(该等待表示即将到来)
for(int i=0;i<mission;i++)
{
wait.push(p[i]);
}
while(!wait.empty() || !ready.empty()) //有未到来任务或就绪队列有任务
{
/* 用inspect这一辅助结构检查即将进行的时间片过程中,
是否有新任务到来,若有,则把要到达任务从等待队列
放进就绪队列,否则放回等待队列 */
wait.swap(inspect);
while(!inspect.empty())
{
ins = &inspect.front();
if( (ins->get_arrive_time() < CPU_time+time_piece) && (ins->get_arrive_time() >= CPU_time) )
{
ready.push(inspect.front());
inspect.pop();
}
else
{
wait.push(inspect.front());
inspect.pop();
}
}
/*若就绪队列任务都执行完,则CPU会空闲一段时间等新任务到达,
此时调CPU时间为等待队列第一个任务的到达时间*/
if(ready.empty())
{
CPU_time = wait.front().get_arrive_time();
ready.push(wait.front());
wait.pop();
}
//下面开始时间片
pcb = &ready.front(); //用pcb指向就绪队列队头
/*若剩余执行时间等于执行时间,说明任务第一次占有CPU
这时的CPU时间就是任务的开始时间*/
if(pcb->remain_time == pcb->get_exe_time())
{
pcb->begin_time = CPU_time;
}
//若在这个时间片结束前执行完了,把这个任务取出就绪队列
if(pcb->remain_time <= time_piece)
{
CPU_time = CPU_time+pcb->remain_time;
pcb->end_time = CPU_time;
out_put.push(ready.front());
ready.pop();
}
//用完这个时间片任务还没执行完,放回就绪队列队尾
else
{
CPU_time += time_piece;
pcb->remain_time -= time_piece;
ready.push(ready.front());
ready.pop();
}
}
cout<<"RR: "<<endl;
while(!out_put.empty())
{
cout<<out_put.front()<<endl;
out_put.pop();
sum_waiting += (out_put.front().begin_time-out_put.front().get_arrive_time());
sum_turnaround += (out_put.front().end_time-out_put.front().get_arrive_time());
}
cout<<"Average waiting time: "<<sum_waiting/mission<<endl;
cout<<"Time for Average Turnaround: "<<sum_turnaround/mission<<endl;
cout<<""<<endl;
}
int main()
{
double temp[4];
ifstream inFile("job.txt");
inFile>>mission;
inFile>>time_piece;
process p[mission];
for(int i=0; i<mission; i++)
{
inFile>>temp[0];
inFile>>temp[1];
inFile>>temp[2];
inFile>>temp[3];
p[i] = process(temp[0],temp[1],temp[2],temp[3]);
}
sort(p, p+mission); //用sort按到达时间对p中任务升序排序
FCFS(p);
SJF(p);
PRO(p);
RR(p);
inFile.close();
return 0;
}
queue::swap()是C++11的stl,在Linux下可以用 g++ -std=c++11 main.cpp编译
这个输入数据的结果我验证没有出错,可能有其它bug。