一个班(20信安)的同学搜到这篇别直接copy我的,代码仅供参考
一、FCFS
代码
#include<bits/stdc++.h>
using namespace std;
float ave_aroundtime; // 平均周转时间
float ave_weight_aroundtime; // 平均带权周转时间
int n;
float nowtime=0;
struct FCFS
{
int name;
char state;
float arrivetime; // 到达时间(即进入外存的时间点)
float servicetime; // 服务时间(所需cpu时间)
float finishtime; // 结束时间
float aroundtime; //周转时间(结束时间-到达时间,即进入外存到执行完毕所需时间)
float weight_aroundtime; // 带权周转时间
};
bool cmp(FCFS a, FCFS b)
{
return a.arrivetime<b.arrivetime;
}
void input(FCFS &p)
{
cout << "请输入作业信息:" << endl;
cout << "名称:";
cin >> p.name;
cout << "到达时间:";
cin >> p.arrivetime;
cout << "服务时间:";
cin >> p.servicetime;
cout << endl;
}
void out(FCFS a)
{
cout << "作业" << a.name << "\t" << a.arrivetime << "\t\t" << a.servicetime << "\t\t" << a.aroundtime << endl;
}
void left_move(vector<FCFS> &a)
{
for(int i=0; i<a.size(); i++){
a[i] = a[i+1];
}
a.pop_back();// 弹出插入队尾的多出的队首元素
}
void run(FCFS &node)
{
node.finishtime = max(nowtime,node.arrivetime)+node.servicetime;
node.aroundtime = node.finishtime - node.arrivetime;
node.weight_aroundtime = node.aroundtime/node.servicetime;
nowtime = node.finishtime;
}
int main(){
vector<FCFS> sort_queue;// 保存排序后的队列
vector<FCFS> back_queue;// 后备队列
vector<FCFS> wait_queue;// 就绪队列
FCFS temp[10];
cout << "输入作业数目:";
cin >> n;
for(int i=0; i<n; i++)
{
input(temp[i]);
back_queue.push_back(temp[i]);// 进入后备队列
}
sort(back_queue.begin(), back_queue.end(), cmp);// 按到达时间从小到大排序
sort_queue = back_queue;
while(!back_queue.empty())
{
// 将一个作业从外存进入内存
wait_queue.push_back(back_queue[0]);
// 后备队列队首弹出
left_move(back_queue);
// 就绪队列作业开始占用cpu
run(temp[wait_queue[0].name-1]);
// 就绪队列作业完成,弹出
wait_queue.clear();
}
cout << "FCFS算法进程的运行顺序为:" << endl;
for(int i=0; i<n; i++)
{
cout << "作业" << sort_queue[i].name << "-->";
}
cout << "over";
cout << "进程完成后具体信息记录:" << endl;
cout << "进程\t到达时间\t服务时间\t周转时间\t" << endl;
for(int i=0; i<n; i++)
{
out(temp[i]);
ave_aroundtime += temp[i].aroundtime;
ave_weight_aroundtime += temp[i].weight_aroundtime;
}
ave_aroundtime/=n;
ave_weight_aroundtime/=n;
cout << "采用FCFS算法算得的平均周转时间为:" << ave_aroundtime << endl;
cout << "采用FCFS算法算得的平均带权周转时间为:" << ave_weight_aroundtime << endl;
}
运行截图
二、SJF
代码
#include<bits/stdc++.h>
using namespace std;
float ave_aroundtime; // 平均周转时间
float ave_weight_aroundtime; // 平均带权周转时间
int n;
float nowtime=0;
struct SJF
{
int name;
char state;
float arrivetime; // 到达时间(即进入外存的时间点)
float servicetime; // 服务时间(所需cpu时间)
float finishtime; // 结束时间
float aroundtime; //周转时间(结束时间-到达时间,即进入外存到执行完毕所需时间)
float weight_aroundtime; // 带权周转时间
};
bool cmp(SJF a, SJF b)
{
return a.arrivetime<b.arrivetime;
}
void input(SJF &p)
{
cout << "请输入作业信息:" << endl;
cout << "名称:";
cin >> p.name;
cout << "到达时间:";
cin >> p.arrivetime;
cout << "服务时间:";
cin >> p.servicetime;
cout << endl;
}
void out(SJF a)
{
cout << "作业" << a.name << "\t" << a.arrivetime << "\t\t" << a.servicetime << "\t\t" << a.aroundtime << endl;
}
void left_move(vector<SJF> &a)
{
for(int i=0; i<a.size(); i++){
a[i] = a[i+1];
}
a.pop_back();// 弹出插入队尾的多出的队首元素
}
void run(SJF &node)
{
node.finishtime = max(nowtime,node.arrivetime)+node.servicetime;
node.aroundtime = node.finishtime - node.arrivetime;
node.weight_aroundtime = node.aroundtime/node.servicetime;
nowtime = node.finishtime;
}
void i_first(vector<SJF> &back_queue, int first_i)
{
// 前移该进程至队首
SJF temp = back_queue[first_i];
for(int i=first_i; i>0; i--)
{
back_queue[i] = back_queue[i-1];
}
back_queue[0] = temp;
}
void zero_flush(vector<SJF> &a)
{
vector<SJF> b;
for(int i=0; i<a.size(); i++)
{
if(a[i].name!=0) b.push_back(a[i]);
}
a.clear();
for(int i=0; i<b.size(); i++)
{
a.push_back(b[i]);
}
}
void fill(vector<SJF> &back_queue, vector<SJF> &sort_queue)
{
if(sort_queue.empty()) return;
for(int i=0; i<sort_queue.size(); i++)
{
if(sort_queue[i].arrivetime <= nowtime)
{
back_queue.push_back(sort_queue[i]);
sort_queue[i].name=0;
}
}
zero_flush(sort_queue);
if(sort_queue.empty()) return;
// 这里很关键,如果执行完进程后后备队列出现空窗期,则直接将nowtime赋值为下一个即将到来的进程的到来时间
if(back_queue.empty())
{
nowtime = sort_queue[0].arrivetime;
fill(back_queue, sort_queue);
}
return;
}
void short_first(vector<SJF> &back_queue)
{
if(back_queue.empty()) return;
int mini=0, minservicetime=back_queue[0].servicetime;
// 遍历寻找在后备队列中的最短服务时间进程
for(int i=0; i<back_queue.size(); i++)
{
if(minservicetime > back_queue[i].servicetime)
{
mini = i;
minservicetime = back_queue[i].servicetime;
}
}
// 前移该进程至队首
SJF temp = back_queue[mini];
for(int i=mini; i>0; i--)
{
back_queue[i] = back_queue[i-1];
}
back_queue[0] = temp;
}
void prt(vector<SJF> a)
{
for(int i=0; i<a.size(); i++)
{
cout << a[i].name << " ";
}
cout << endl;
}
int main(){
vector<SJF> sort_queue;// 保存排序后的队列
vector<SJF> back_queue;// 后备队列
vector<SJF> wait_queue;// 就绪队列
vector<SJF> over_queue;// 执行完毕队列
SJF temp[10];
cout << "输入作业数目:";
// input
cin >> n;
for(int i=0; i<n; i++)
{
input(temp[i]);
sort_queue.push_back(temp[i]);// 进入后备队列
}
sort(sort_queue.begin(), sort_queue.end(), cmp);// 按到达时间从小到大排序
// 第一次进程调度
back_queue.push_back(sort_queue[0]);// 第一个进程直接进入
left_move(sort_queue);
// 一次进程调度
wait_queue.push_back(back_queue[0]);
left_move(back_queue);
run(temp[wait_queue[0].name-1]);
over_queue.push_back(wait_queue[0]);
wait_queue.clear();
cout << nowtime << " ";
cout << "back:";
prt(back_queue);
cout << "sort:";
prt(sort_queue);
while(over_queue.size()!=n)
{
fill(back_queue, sort_queue); // 根据上一个进程结束时间nowtime填充后备队列back_queue
short_first(back_queue); // 前移后备队列中服务时间最短的进程到队首
// cout << back_queue[0].name << endl;
cout << nowtime << " ";
cout << "back:";
prt(back_queue);
cout << "sort:";
prt(sort_queue);
wait_queue.push_back(back_queue[0]); // 后备队列队首进程放到就绪队列中
left_move(back_queue);// 后备队列队首弹出
run(temp[wait_queue[0].name-1]);// 就绪队列作业开始占用cpu
over_queue.push_back(wait_queue[0]);
wait_queue.clear();// 就绪队列作业完成,弹出
}
cout << "SJF算法进程的运行顺序为:" << endl;
for(int i=0; i<n; i++)
{
cout << "作业" << over_queue[i].name << "-->";
}
cout << "over" << endl;
cout << "进程完成后具体信息记录:" << endl;
cout << "进程\t到达时间\t服务时间\t周转时间\t" << endl;
for(int i=0; i<n; i++)
{
out(temp[i]);
ave_aroundtime += temp[i].aroundtime;
ave_weight_aroundtime += temp[i].weight_aroundtime;
}
ave_aroundtime/=n;
ave_weight_aroundtime/=n;
cout << "采用SJF算法算得的平均周转时间为:" << ave_aroundtime << endl;
cout << "采用SJF算法算得的平均带权周转时间为:" << ave_weight_aroundtime << endl;
}
运行截图
三、小结
-
执行的进程数据是参考ppt最后给出的测试用例,为了简单期间ABCDE进程名称设置为12345.
-
作业调度的过程没有用一个时钟进行不断推进,而是利用每一个执行进程直接计算结束时间,因此会出现进程执行完,后备队列依然为空的情况,这里就需要判断进程是否全部执行完毕,即一开始需要先输入进程的个数,否则无法判断后续是否还有未到来的进程。
-
短作业调度算法的过程中,需要在每次进程执行完毕,在后备队列内进程中搜索服务时间最短的进程进行执行,在这个过程中,需要找到合适的进程,将其挪到后备队列队首,出队放入就绪队列,然后占用CPU时间