操作系统课程设计
三种作业调度算法实现
短作业优先算法、先来先服务算法、小作业优先算法
代码
#include<iostream>
#include<string>
using namespace std;
class JobControlBlock // 创建进程类,存放进程的基本信息
{
public:
string JobName; //进程名
float ArriveTime; //到达时间
float ServiceTime; //服务时间
float StartTime; //开始运行时间
float FinishTime; //完成运行时间
float MemorySpace; //存储空间
float TurnaroundTime; //周转时间
float WeightedTuraroundTime; //带权周转时间
float AverageTurnaroundTime; //平均周转时间
char State;//状态
};
void CreatJobContolBlock(JobControlBlock *p, int n) //创建n个进程
{
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 创建进程 " << endl;
cout << "******************************************************************************************" << endl;
cout << endl;
for (int i = 0; i < n; i++)
{
cout << "请输入第" << i + 1
<< "个作业的名字、到达时间、服务时间、存储空间(例如:A 12 8 10):";
cin >> p[i].JobName;
cin >> p[i].ArriveTime;
cin >> p[i].ServiceTime;
cin >> p[i].MemorySpace;
p[i].StartTime = 0;
p[i].FinishTime = 0;
p[i].TurnaroundTime = 0;
p[i].WeightedTuraroundTime = 0;
//p.push_back(TheP); //在队尾插入一个元素
}
}
void PrintForEasyJob(JobControlBlock* p, int n)//输出部分进程的信息
{
cout << endl;
cout << "******************************************************************************************" << endl;
cout<<"** 进程名\t到达时间 服务时间 储存空间" << endl;
for (int i = 0; i < n; i++)
{
cout << "** " << p[i].JobName << "\t";
cout << p[i].ArriveTime << "\t ";
cout << p[i].ServiceTime << "\t ";
cout<<p[i].MemorySpace<< "\t " << endl;
}
cout << "******************************************************************************************" << endl;
cout << endl;
}
void PrintJob(JobControlBlock *p,int n) //输出所有进程的信息
{
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 进程名\t到达时间 服务时间 开始时间 完成时间"
<< " 周转时间 带权周转时间 储存空间" << endl;
for (int i = 0; i < n; i++)
{
cout <<"** "<< p[i].JobName << "\t" << p[i].ArriveTime << "\t "
<< p[i].ServiceTime << "\t ";
cout << p[i].StartTime << "\t " << p[i].FinishTime << "\t "
<< p[i].TurnaroundTime << "\t ";
cout << p[i].WeightedTuraroundTime << "\t " <<
p[i].MemorySpace
<< "\t " << endl;
}
cout << "******************************************************************************************" << endl;
cout << endl;
}
void SortForArriveTime(JobControlBlock* p, int n)//按照到达时间排序
{
for (int i = 0; i < n - 1; i++)
for (int j = 0; j <n- i-1; j++)
{
if (p[j].ArriveTime >p[j + 1].ArriveTime)
{
//swap(p[j], p[j - 1]); //是不是不能用swap简单交换
JobControlBlock temp = p[j];
//temp = p[j];
p[j] = p[j +1];
p[j + 1] = temp;
}
}
}
void SortForMemorySpace(JobControlBlock* p, int n)//按照储存空间排序
{
for (int i = 0; i < n - 1; i++) //先按照到达时间升序排序
for (int j = 0; j < n - i - 1; j++)
{
if (p[j].ArriveTime > p[j + 1].ArriveTime)
{
JobControlBlock temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
}
}
cout << "先按照到达时间升序排序完成" << endl;
PrintForEasyJob(p, n); //打印进程结果
int k = 1; //记录现在有多少个进程的到达时间在已完成时间之前
float NewArriveTime = p[0].ArriveTime + p[0].ServiceTime;
//应该要进行n-1论排序。
for (int x = 1; x < n; x++)//n-1论排序。 x这个变量包含很多
{
int z = 0;//记录这一轮多少个进程需要排序
{
int i = 0;
//cout << "进来了" << endl;
//cout << p[3].ArriveTime << endl;
while (i < n)
{
if (p[x + i].ArriveTime <= NewArriveTime && x + i < n)
{
i++;
z++;
//cout << z << ":Z" << endl;
}
else
{
break;
}
}
}
//cout << "是不是卡这里了" << endl;
//cout << "z:" << z << endl;
for (int i = 0; i < z - 1; i++)//给z个进程按照作业时间长短排序 冒泡排序写法
for (int j = 0; j < z - i - 1; j++)
{
if (p[x + j].MemorySpace > p[x + j + 1].MemorySpace)
{
JobControlBlock temp = p[x + j];
p[x + j] = p[x + j + 1];
p[x + j + 1] = temp;
}
}
//cout << "让我看看到达卡哪里了" << endl;
NewArriveTime = NewArriveTime + p[x].ServiceTime;
}
}
void SortForServiceTime(JobControlBlock* p, int n)//按照服务时间排序
{
for (int i = 0; i < n - 1; i++) //先按照到达时间升序排序
for (int j = 0; j < n - i - 1; j++)
{
if (p[j].ArriveTime > p[j + 1].ArriveTime)
{
JobControlBlock temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
}
}
cout << "先按照到达时间升序排序完成" << endl;
PrintForEasyJob(p, n); //打印进程结果
int k = 1; //记录现在有多少个进程的到达时间在已完成时间之前
float NewArriveTime = p[0].ArriveTime+p[0].ServiceTime;
//应该要进行n-1论排序。
for (int x = 1; x < n; x++)//n-1论排序。 x这个变量包含很多
{
int z = 0;//记录这一轮多少个进程需要排序
{
int i = 0;
//cout << "进来了" << endl;
//cout << p[3].ArriveTime << endl;
while (i<n)
{
if (p[x + i].ArriveTime <= NewArriveTime && x+i<n)
{
i++;
z++;
//cout << z << ":Z" << endl; 是不是这里错了
}
else
{
break;
}
}
}
//cout << "是不是卡这里了" << endl;
//cout << "z:" << z << endl;
for (int i = 0; i < z - 1; i++)//给z个进程按照作业时间长短排序 冒泡排序写法
for (int j = 0; j < z - i - 1; j++)
{
if (p[x + j].ServiceTime > p[x + j + 1].ServiceTime)
{
JobControlBlock temp = p[x + j];
p[x + j] = p[x + j + 1];
p[x + j + 1] = temp;
}
}
//cout << "让我看看到达卡哪里了" << endl;
NewArriveTime = NewArriveTime + p[x].ServiceTime;
}
}
void JobScheduling(JobControlBlock* p, int n)
{
//防止多次调用有初始值,先全部初始化;
for (int i = 0; i < n; i++)
{
p[i].StartTime = 0;
p[i].FinishTime = 0;
p[i].TurnaroundTime = 0;
p[i].WeightedTuraroundTime = 0;
}
for (int i = 0; i < n; i++)
{
if (i == 0)
{
p[i].StartTime = p[i].ArriveTime;
p[i].FinishTime = p[i].StartTime + p[i].ServiceTime;
p[i].TurnaroundTime = p[i].FinishTime - p[i].ArriveTime;
p[i].WeightedTuraroundTime = p[i].TurnaroundTime / p[i].ServiceTime;
}
else
{
if (p[i - 1].FinishTime > p[i].ArriveTime)
{
p[i].StartTime = p[i - 1].FinishTime;
}
else
{
p[i].StartTime = p[i].ArriveTime;
}
p[i].StartTime = p[i-1].FinishTime;
p[i].FinishTime = p[i].StartTime + p[i].ServiceTime;
p[i].TurnaroundTime = p[i].FinishTime - p[i].ArriveTime;
double W = 0.0;
W = (double)p [i].TurnaroundTime / p[i].ServiceTime;
p[i].WeightedTuraroundTime = W;
}
}
}
void FirstComeFirstServeArithmetic(JobControlBlock *p, int n, float &TotolTurnaroundTimeFor1, float& AverageTurnaroundTimeFor1, float& TotolWeightedTuraroundTimeFor1, float& AverageWeightedTuraroundTimeFor1) //先来先服务算法
{
SortForArriveTime(p, n); //先按照到达时间给进程排序
cout<< endl;
cout<<"按照到达时间给进程排序后的结果" << endl;
PrintForEasyJob(p, n); //打印进程结果
cout << endl;
cout << "算法调度完成后结果" << endl;
JobScheduling(p,n); //进程调度过程
PrintJob(p, n); //打印进程结果
for (int i = 0; i < n; i++)
{
TotolTurnaroundTimeFor1 = TotolTurnaroundTimeFor1 + p[i].TurnaroundTime;
TotolWeightedTuraroundTimeFor1 = TotolWeightedTuraroundTimeFor1 + p[i].WeightedTuraroundTime;
}
cout << "总周转时间" << TotolTurnaroundTimeFor1 << endl;
AverageTurnaroundTimeFor1 = TotolTurnaroundTimeFor1 / n;
cout << "平均周转时间" << AverageTurnaroundTimeFor1 << endl;
cout << "总带权周转时间" << TotolWeightedTuraroundTimeFor1 << endl;
AverageWeightedTuraroundTimeFor1 = TotolWeightedTuraroundTimeFor1 / n;
cout << "平均带权周转时间" << AverageWeightedTuraroundTimeFor1 << endl;
}
void ShortJobFirstAlgorithm(JobControlBlock* p, int n, float &TotolTurnaroundTimeFor2, float &AverageTurnaroundTimeFor2, float &TotolWeightedTuraroundTimeFor2, float &AverageWeightedTuraroundTimeFor2) // 短作业优先算法
{
SortForServiceTime(p, n); //先按照服务时间长度给进程排序
cout << endl;
cout << "按照服务时间长度给进程排序后的结果" << endl;
PrintForEasyJob(p, n); //打印进程调度排序
cout << endl;
cout << "算法调度完成后结果" << endl;
JobScheduling(p, n); //进程调度过程
PrintJob(p, n); //打印进程结果
for (int i = 0; i < n; i++)
{
TotolTurnaroundTimeFor2 = TotolTurnaroundTimeFor2 + p[i].TurnaroundTime;
TotolWeightedTuraroundTimeFor2 = TotolWeightedTuraroundTimeFor2 + p[i].WeightedTuraroundTime;
}
cout << "总周转时间" << TotolTurnaroundTimeFor2 << endl;
AverageTurnaroundTimeFor2 = TotolTurnaroundTimeFor2 / n;
cout << "平均周转时间" << AverageTurnaroundTimeFor2 << endl;
cout << "总带权周转时间" << TotolWeightedTuraroundTimeFor2 << endl;
AverageWeightedTuraroundTimeFor2 = TotolWeightedTuraroundTimeFor2 / n;
cout << "平均带权周转时间" << AverageWeightedTuraroundTimeFor2 << endl;
}
void MinimumJobFirstAlgorithm(JobControlBlock* p, int n, float &TotolTurnaroundTimeFor3, float &AverageTurnaroundTimeFor3, float &TotolWeightedTuraroundTimeFor3, float &AverageWeightedTuraroundTimeFor3) // 小作业优先算法
{
SortForMemorySpace(p, n); //先按照储存空间给进程排序
cout << endl;
cout << "按照储存空间给进程排序后的结果" << endl;
PrintForEasyJob(p, n); //打印进程结果
cout << endl;
cout << "算法调度完成后结果" << endl;
JobScheduling(p, n); //进程调度过程
PrintJob(p, n); //打印进程结果
for (int i = 0; i < n; i++)
{
TotolTurnaroundTimeFor3 = TotolTurnaroundTimeFor3 + p[i].TurnaroundTime;
TotolWeightedTuraroundTimeFor3 = TotolWeightedTuraroundTimeFor3 + p[i].WeightedTuraroundTime;
}
cout << "总周转时间" << TotolTurnaroundTimeFor3 << endl;
AverageTurnaroundTimeFor3 = TotolTurnaroundTimeFor3 / n;
cout << "平均周转时间" << AverageTurnaroundTimeFor3 << endl;
cout << "总带权周转时间" << TotolWeightedTuraroundTimeFor3 << endl;
AverageWeightedTuraroundTimeFor3 = TotolWeightedTuraroundTimeFor3 / n;
cout << "平均带权周转时间" << AverageWeightedTuraroundTimeFor3 << endl;
cout << endl;
}
int menu()
{
CHOOSEAGAIN:
int flag = 5;
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 请选择要进行的操作 **" << endl;
cout << "** 1.创建作业控制块 **" << endl;
cout << "** 2.分别三种算法进行作业调度 **" << endl;
cout << "** 0.退出 **" << endl;
cout << "******************************************************************************************" << endl;
cout << endl;
cout << "请输入你的选择:" ;
cin >> flag;
if (flag != 0 && flag != 1 && flag != 2)
{
cout << endl;
cout << "输入错误,请重新输入 !" << endl;
cout << "flag 的选择不能为:" << flag << endl;
//menu(); //这样写递归我还是不太行
goto CHOOSEAGAIN; //再次选择
}
return flag;
}
void JudgeTheMeritsOfAnAlgorithm(float &AverageTurnaroundTimeFor1, float &AverageWeightedTuraroundTimeFor1, float &AverageTurnaroundTimeFor2, float &AverageWeightedTuraroundTimeFor2, float &AverageTurnaroundTimeFor3, float &AverageWeightedTuraroundTimeFor3)
{
string n = "wu";
float b1 = AverageTurnaroundTimeFor1 + AverageWeightedTuraroundTimeFor1;
float b2 = AverageTurnaroundTimeFor2 + AverageWeightedTuraroundTimeFor2;
float b3 = AverageTurnaroundTimeFor3 + AverageWeightedTuraroundTimeFor3;
string B1 = "先来先服务算法";
string B2 = "短作业优先算法";
string B3 = "小作业优先算法";
//下面是三个数由小到大排序
if (b1>b2)
{
n = B1;
B1 = B2;
B2 = n;
}
if (b1>b3)
{
n = B1;
B1 = B3;
B3 = n;
}
if (b2>b3)
{
n = B2;
B2 = B3;
B3 = n;
}
cout << "三种不同作业调度算法在本次进程的优劣比较:" << endl;
cout << "******************************************************************************************" << endl;
cout << "** 平均周转时间分别是:" << endl;
cout << "** 先来先服务算法的平均周转周期为:" << AverageTurnaroundTimeFor1 << endl;
cout << "** 短作业优先算法的平均周转周期为:" << AverageTurnaroundTimeFor2 << endl;
cout << "** 小作业优先算法的平均周转周期为:" << AverageTurnaroundTimeFor3 << endl;
cout << "******************************************************************************************" << endl;
cout << "** 平均带权周转时间分别是:" << endl;
cout << "** 先来先服务算法的平均带权周转周期为:" << AverageWeightedTuraroundTimeFor1 << endl;
cout << "** 短作业优先算法的平均带权周转周期为:" << AverageWeightedTuraroundTimeFor2 << endl;
cout << "** 小作业优先算法的平均带权周转周期为:" << AverageWeightedTuraroundTimeFor3 << endl;
cout << "******************************************************************************************" << endl;
cout << "** 经过计算,综合平均周转周期和平均带权周期,本次进程中"<<endl;
cout << endl;
cout <<"** "<<B1<<"最优 "<<B2<<"次之 "<<B3<<"最次 **"<< endl;
cout << endl;
cout << "******************************************************************************************" << endl;
}
int main()
{
//先来先服务
float TotolTurnaroundTimeFor1 = 0;
float AverageTurnaroundTimeFor1 = 0;
float TotolWeightedTuraroundTimeFor1 = 0;
float AverageWeightedTuraroundTimeFor1 = 0;
//短作业优先
float TotolTurnaroundTimeFor2 = 0;
float AverageTurnaroundTimeFor2 = 0;
float TotolWeightedTuraroundTimeFor2 = 0;
float AverageWeightedTuraroundTimeFor2 = 0;
//小作业优先
float TotolTurnaroundTimeFor3 = 0;
float AverageTurnaroundTimeFor3 = 0;
float TotolWeightedTuraroundTimeFor3 = 0;
float AverageWeightedTuraroundTimeFor3 = 0;
int MenuFlag = 0;
//获得输入选择的返回值
MenuFlag = menu();
//cout << MenuFlag << endl;
if (MenuFlag == 2) //防止未创建进程控制块就进行调度算法,以及
{
cout << "####" << endl;
cout << "错误,请先创建作业控制块" << endl;
MenuFlag = menu();
}
else if (MenuFlag == 0)//直接结束进程
{
return 0;
}
RECREATPROCESSCONTROLBLOCK: //这个goto语句用来防止再次创建进程
//创建进程控制块
int n = 0;
cout << "请输入作业的个数:" << endl;
cin >> n;
//if(n>1000||n<1) //想写一个防止输入字符和输入进程个数多大,但是不会写
JobControlBlock* p = new JobControlBlock[n];
CreatJobContolBlock(p, n); //创建进程
cout <<"作业创建完成"<< endl;
//一个作业调度完成后,再次回到主菜单,进行选择:
ONCEAGAIN:
//创建完进程块后,再次进入主菜单进行选择
MenuFlag = menu(); //调用主菜单函数并获取选择的返回值
if (MenuFlag == 1) //如果用户想再次创建进程
{
goto RECREATPROCESSCONTROLBLOCK;
}
if (MenuFlag == 2) //正常来说,第二步进行作业调度
{
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 采用先来先服务算法进行作业调度 **" << endl;
cout << "******************************************************************************************" << endl;
FirstComeFirstServeArithmetic(p, n, TotolTurnaroundTimeFor1, AverageTurnaroundTimeFor1, TotolWeightedTuraroundTimeFor1, AverageWeightedTuraroundTimeFor1); //先来先服务算法
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 采用短作业优先算法进行作业调度 **" << endl;
cout << "******************************************************************************************" << endl;
ShortJobFirstAlgorithm(p, n, TotolTurnaroundTimeFor2, AverageTurnaroundTimeFor2, TotolWeightedTuraroundTimeFor2, AverageWeightedTuraroundTimeFor2); //短作业优先算法
cout << endl;
cout << "******************************************************************************************" << endl;
cout << "** 采用小作业优先算法进行作业调度 **" << endl;
cout << "******************************************************************************************" << endl;
MinimumJobFirstAlgorithm(p, n, TotolTurnaroundTimeFor3, AverageTurnaroundTimeFor3, TotolWeightedTuraroundTimeFor3, AverageWeightedTuraroundTimeFor3); //小作业优先
cout << "******************************************************************************************" << endl;
JudgeTheMeritsOfAnAlgorithm(AverageTurnaroundTimeFor1, AverageWeightedTuraroundTimeFor1, AverageTurnaroundTimeFor2, AverageWeightedTuraroundTimeFor2, AverageTurnaroundTimeFor3, AverageWeightedTuraroundTimeFor3);
}
if (MenuFlag == 0) //退出整个代码运行
{
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~本次代码运行完成,完结撒花 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~☆*: .。. o(≧▽≦)o .。.:*☆~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
return 0;
}
//一次进程完成后,再次选择想要进行的操作。也用goto语句吧
goto ONCEAGAIN;
delete[] p;
//return 0;
}