一、实验目的:
目的:了解并掌握作业调度的功能,熟悉并掌握各种作业调度算法。
任务:模拟实现先来先服务或者短作业优先调度算法。
二、实验内容:
1、实验内容
模拟实现SJF调度。
设置作业体:作业名,作业的到达时间,服务时间,作业状态(W——等待,R——运行,F——完成),作业间的链接指针;
作业初始化:由用户输入作业名、服务时间、到达时间进行初始化,同时,初始化作业的状态为W。
显示函数:在作业调度前、调度中和调度后进行显示。
排序函数:对等待状态的作业按照调度算法排序(不同的调度算法排序方式不同),注意考虑到达时间。
调度函数:每次从等待队列队首调度已到达的适合的作业执行,状态变化。当服务结束时,状态变为F。
删除函数:撤销状态为F的作业。
2、实验要求
(1)测试数据可以随即输入或从文件中读入;
(2)必须要考虑到作业的到达时间;
(3)最终能够计算每一个作业的周转时间、带权周转时间。
三、实验代码 (C++)
1、首先定义函数体
struct process
{
string pid; //作业名(作业号)
double come_time; //到达时
double run_time; //运行时
double begin_time; //开始时
double over_time; //完成时
double round_time; //周转时
double avg_time; //带权周转时
double HRR; //响应比
char state; // 状态
double need_time; // 所剩余需要服务的时间
} pc[MAXSIZE]; //作业数
2、定义完函数体后,对进程进行排序算法。
bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}
3、写完排序函数后,计算进程的开始时间与到达时间
void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
for (int i = 0; i < number; i++)
{
if (i == 0)
{
pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
}
else
{
pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
}
pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
}
}
4、进行对周转时间,带权周转时间的计算
- 完成时间=开始时间+服务时间
- 周转时间=完成时间-到达时间
- 带权周转时间=周转时间/服务时间
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
for (int i = 0; i < number; ++i)
{
pc[i].round_time = pc[i].over_time - pc[i].come_time; // 周转时 = 完成时间 - 到达时间
pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
}
}
5、计算完成后,写SJF的函数体
void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
sort(pc, pc + number, CmpByComeTime); // 先按到达时排序
sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
get_beginAndOver_time();
get_roundAndAvg_time();
}
四、实验结果
如图
五、完整代码
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXSIZE 5 // 作业数
int number; // 用户输入的进程数量
struct process
{
string pid; //作业名(作业号)
double come_time; //到达时
double run_time; //运行时
double begin_time; //开始时
double over_time; //完成时
double round_time; //周转时
double avg_time; //带权周转时
double HRR; //响应比
char state; // 状态
double need_time; // 所剩余需要服务的时间
} pc[MAXSIZE]; //作业数
bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}
void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
for (int i = 0; i < number; i++)
{
if (i == 0)
{
pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
}
else
{
pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
}
pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
}
}
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
for (int i = 0; i < number; ++i)
{
pc[i].round_time = pc[i].over_time - pc[i].come_time; // 周转时 = 完成时间 - 到达时间
pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
}
}
void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
sort(pc, pc + number, CmpByComeTime); // 先按到达时排序
sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
get_beginAndOver_time();
get_roundAndAvg_time();
}
void qianprint()
{
cout << endl;
cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
<< "开始时" << '\t' << "完成时" << '\t' << "状态" << '\t'
<< endl;
for (int i = 0; i < number; ++i)
{
/* code */
// sum_round_time = pc[i].over_time;
pc[i].state='W';
}
for (int i = 0; i < number; ++i)
{
cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
<< pc[i].run_time << '\t' << pc[i].begin_time << '\t'
<< pc[i].over_time << '\t' << pc[i].state<<'\t' << endl;
}
}
void printProcess() // 打印作业的过程
{
double atime=1;
double sum_round_time = 0.0;
for (int i = 0; i < number; ++i)
{
/* code */
sum_round_time = pc[i].over_time;
pc[i].state='W';
}
// cout<<sum_round_time<<endl;
for (atime;atime<=sum_round_time;++atime){
cout<<'\t'<<endl;
cout << "第"<<atime<<"个时间周期" <<'\t'<< endl;
cout << endl;
cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
<< "开始时" << '\t' << "需要时" << '\t' << "状态" << '\t'
<< endl;
for (int i = 0; i < atime&&i<number; ++i)
{
for (int j = 0; j < number; ++j)
{
if (atime==pc[j].come_time&&(pc[j-1].state=='\0'||pc[j-1].state=='F'))
{
pc[j].state='R';
}
else if(atime>=pc[j].over_time){
pc[j].state='F';
pc[j+1].state='R';
}
}
pc[i].need_time=pc[i].over_time-atime;
if(pc[i].need_time>=0)
{
pc[i].need_time=pc[i].need_time;
}
else
{
pc[i].need_time=0;
}
if(atime>=pc[i].come_time){
cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
<< pc[i].run_time << '\t' << pc[i].begin_time << '\t'
<< pc[i].need_time << '\t' << pc[i].state<<'\t' << endl;
}
}
}
}
void printResult() // 打印输出作业的各个时间值
{
cout << "执行顺序:"; // << endl
for (int i = 0; i < number; ++i)
{
/* code */
cout << pc[i].pid<< " ";
}
cout << endl;
cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
<< "开始时" << '\t' << "完成时" << '\t' << "周转时" << '\t'
<< "带权周转时" << '\t' << endl;
sort(pc, pc + number, CmpByPid);
double sum_round_time = 0.0;
double avg_sum_round_time = 0.0; // 平均周转时间
double sum_avg_time = 0.0;
double avg_sum_avg_time = 0.0; // 平均带权周转时间
for (int i = 0; i < number; ++i)
{
sum_round_time += pc[i].round_time;
sum_avg_time += pc[i].avg_time;
cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
<< pc[i].run_time << '\t' << pc[i].begin_time << '\t'
<< pc[i].over_time << '\t' << pc[i].round_time << '\t'
<< pc[i].avg_time << endl;
}
avg_sum_round_time = sum_round_time * 1.0 / number;
avg_sum_avg_time = sum_avg_time * 1.0 / number;
cout << "平均周转时间: " << avg_sum_round_time << endl
<< "平均带权周转时间: " << avg_sum_avg_time << endl;
}
int main() // 入口函数
{
int atime=1;
cout << "请输入进程个数:";
cin >> number;
cout << endl;
cout << "请分别输入进程的名称、到达时间、服务时间:" << endl;
for (int i = 0; i < number; i++)
{
cin >> pc[i].pid >> pc[i].come_time >> pc[i].run_time;
}
cout << endl;
SJF();
cout << "运行前的任务:" <<'\t'<< endl;
qianprint();
cout << "运行中的任务调度过程:" <<'\t'<< endl;
printProcess();
cout << "the results of SJF are:" << endl;
printResult();
system("pause");
return 0;
}