网站备案接入商是什么/微信指数官网
用高级语言仿真实现一个通用处理机调度演示程序。基本要求如下:
(1)进程调度算法包括:先来先服务算法、短作业优先算法、静态优先权调度算法以及高响应必优先调度算法,并采用菜单进行算法的选择;
(2)每一个进程由一个PCB标识,其内容可以根据具体情况设定;
(3)进程数、进入内存时间、要求服务时间、作业大小、优先级等可以在界面设定,也可以从外部文件中读取样例数据;
(4)在运行中显示各进程的状态:就绪和执行;
(5)采用可视化界面,可在进程调度过程中随时暂停调度,查看当前进程的状态;
(6)有算法的性能比较功能,可以比较同一组数据在不同调度算法下的平均周转时间;
(7)有一定的数据容错能力。
NOTES:
虽然最近比较忙,但是还是头铁的选择了自己写代码,而不是copy网上的,所有代码都是我自己写的,由于水平限制所以难免有问题,希望大家多指正,参考时请自行测验,代码后面写的那些测试案例得出的结果是正确的。
题目要求中的4、5两项要求由于时间原因,而且我没能清楚理解第四个要求的意义(个人觉得因为只让显示就绪或者执行,那么显示出来的自然就是执行的,其他的自然就是就绪了),所以没有写这个 步骤;第五个要求因为要每一步都输入一个字符让其继续运行,导致页面过于混乱,操作过于复杂,所以我选择了去掉。
另外:还是由于时间原因我没有考虑当一个进程运行完以后,就绪队列中没有任何一个进程的情况
希望各位同学以后在做课程设计时还是应当尽量追求完美,忙于考研,我已经不能再去熬一夜了。。。
总结:
这可能是我目前为止独立写的最长的代码,熬了两次夜,起来俩痘......,不过收获颇多
1:写程序之前先构造了大体框架,感受到了盖房子的过程
2:代码中命名、注释、缩进等基本统一标准,整体美观
3:实现某个功能的各个函数之间相对独立(比如:Calculate和Output)方便单独调用和修改
发现的问题:
1:虽然有了大体框架,但是对各个部分了解不深就草草开写,导致最开始写出的几个算法都出现逻辑错误,不得不修改大部分代码,浪费了很多时间。
2:刚开始时函数的功能不够独立,比如Output中包含了计算和输出两部分,要计算就不得不输出,当然,下面的代码中我已经修改了。
3:...问题还有许多,希望大佬们多指正,代码错误或者代码习惯不好都可以,欢迎大家留言
总之,很开心能独立快速的写出这个课程设计,革命尚未成功,同志还需努力。
代码(使用DEV编写):
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<windows.h>
#define maxn 30
#define INF 10000
using namespace std;//函数声明
int Turn();
int Menu();
int Select();
int Input();
int FCFS(int n,bool m);
int SJF(int n,bool m);
int HRRN(int n,bool m);
int SP(int n,bool m);
void CompareACT(int n);//初始化PCB
struct Node{string name; //进程名int priority; // 优先级double arrivetime; //进程到达时间double begintime; //进程开始执行时间double waittime; //进程等待时间double runtime; //需要运行时间double finishtime; //进程结束时的时间double cyclyingtime;//进程周转时间 double RR;//当前进程的相应比 bool state; //当前进程状态 未执行false 已经执行 = true
}P[maxn];
Node rem[maxn]; //功能5中会用 //主函数
int main()
{Turn();return 0;
}
//循环过程
int Turn()
{Menu();int n = Select();int count = Input(); //统计进程数printf("\n提示:");switch(n){case 1: printf("当前使用的算法是”先来先服务算法“\n\n");FCFS(count,true);break;case 2: printf("当前使用的算法是”短进程优先算法“\n\n");SJF(count,true);break;case 3: printf("当前使用的算法是”高响应比优先算法“\n\n");HRRN(count,true);break;case 4: printf("当前使用的算法是”静态优先权算法“\n\n");SP(count,true);break;case 5: printf("比较各算法的平均周转时间\n\n");CompareACT(count);break; }
}
//选择菜单
int Select()
{int n;while(1){ cin>>n;if(n<1||n>5) cout<<"输入有误请重新输入!!!"<<endl;else{system("cls");break;}}return n;
}
//菜单:选择算法
int Menu()
{printf("\n\n\n");printf("\t\t\t**********************请选择算法(1-5)*************************\n\n");printf("\t\t\t\t1-- 先来先服务算法(FCFS)\n\n");printf("\t\t\t\t2-- 短作业优先算法(SJF)\n\n");printf("\t\t\t\t3-- 高相应比优先调度算法(HRRN)\n\n");printf("\t\t\t\t4-- 静态优先权调度算法(SP)\n\n");printf("\t\t\t\t5-- 比较各个算法的平均周转时间\n\n");cout<<" 请输入选择的序号: ";
}//输入内容
int Input()
{int progress_num; //进程总数cout<<"请输入进程总数:";cin>>progress_num;cout<<"请选择输入方式:手动输入(H/h),文件输入(F/f): "<<endl;cout<<"进程名 优先级 到达时间 需要运行时间 "<<endl;cout<<"------------------------------------------------------"<<endl;string str; cin>>str;if(str == "H"||str == "h"){cout<<"请手动输入:"<<endl; for(int i=1;i<=progress_num;++i){ //注意从1开始cin>>P[i].name; rem[i].name= P[i].name;cin>>P[i].priority; rem[i].priority = P[i].priority;cin>>P[i].arrivetime; rem[i].arrivetime = P[i].arrivetime;cin>>P[i].runtime;rem[i].runtime = P[i].runtime;P[i].state = false; //输入的进程默认都是就绪状态rem[i].state = false;}}if(str == "F"||str == "f"){ //文件读写 freopen("in.txt","r",stdin);for(int i=1;i<=progress_num;++i){ //注意从1开始cin>>P[i].name; rem[i].name= P[i].name;cin>>P[i].priority; rem[i].priority = P[i].priority;cin>>P[i].arrivetime; rem[i].arrivetime = P[i].arrivetime;cin>>P[i].runtime;rem[i].runtime = P[i].runtime;P[i].state = false; //输入的进程默认都是就绪状态rem[i].state = false;}fclose(stdin);cout<<"自动输入完毕!"<<endl;}return progress_num;
}
//计算各个属性
int Calculate(int i,int flag)
{if(i==1||P[i].arrivetime>=P[flag].finishtime){ //如果是第一个进程或者此进程到达之前前一个进程已经执行完毕P[i].waittime = 0; //那么等待时间为0P[i].begintime = P[i].arrivetime; //当前进程的开始时间 = 到达时间P[i].finishtime = P[i].begintime + P[i].runtime; //进程的完成时间=到达时间+运行时间}else{P[i].waittime = P[flag].finishtime-P[i].arrivetime; //否则,等待时间=上一个进程的完成时间-当前进程的到达时间P[i].begintime = P[flag].finishtime; //当前进程开始时间 = 上一个进程的完成时间P[i].finishtime = P[i].begintime+P[i].runtime;//完成时间=开始时间+当前进程运行时间}P[i].cyclyingtime = P[i].finishtime-P[i].arrivetime; //计算周转时间 P[i].RR = (double)(P[i].waittime +P[i].runtime)/P[i].runtime; //计算响应比
}
//输出内容
int Output(int i,int flag) //传入当前进程号,和上一步执行的进程号
{Calculate(i,flag);cout<<"进程名 到达时间 等待时间 开始时间 运行时间 完成时间 优先权 周转时间 带权周转时间 "<<endl;cout<<"-------------------------------------------------------------------------------------------"<<endl;cout<<" "<<P[i].name;printf("%10.2f",P[i].arrivetime);printf("%10.2f",P[i].waittime);printf("%10.2f",P[i].begintime);printf("%10.2f",P[i].runtime);printf("%10.2f",P[i].finishtime);printf("%10.d",P[i].priority);printf("%10.2f",P[i].cyclyingtime);printf("%10.2f/%.2f\n",P[i].cyclyingtime,P[i].runtime);
}
void ReturnMenu() //返回菜单选项
{cout<<"演示结束!"<<endl;cout<<"按M(m)返回菜单"<<endl; string ss;cin>>ss;if(ss=="M"||ss=="m") {system("cls");Turn();}
}
//计算平均周转时间
void ACTime(int n,bool m)
{double sumcyclyingtime = 0;double avercyclyingtime;for(int i=1;i<=n;++i){sumcyclyingtime += P[i].cyclyingtime;}avercyclyingtime = sumcyclyingtime / n;printf("平均周转时间 = %.2f\n",avercyclyingtime); if(m == 1) ReturnMenu();
}bool FCFS_cmp(Node a,Node b)
{return a.arrivetime < b.arrivetime; //按到达时间从早到晚
}
int FCFS(int n,bool m)
{sort(P+1,P+n+1,FCFS_cmp); //将进程根据arrivetime排序for(int i=1;i<=n;++i){if(m == 1) Output(i,i-1);else Calculate(i,i-1);}ACTime(n,m);
}bool SJF_cmp(Node a,Node b)
{if(a.arrivetime == b.arrivetime) //如果同时到达 return a.runtime < b.runtime; //按作业由小到大排序 return a.arrivetime<b.arrivetime; //否则按到达时间排序
}
int SJF(int n,bool m)
{int flag = 0;int T = n;while(T--){int pre = flag; //pre:先前执行的进程sort(P+1,P+n+1,SJF_cmp);double minx = INF; //用来找运行时间最短的进程for(int i=1;i<=n;++i){if(P[i].state==true) continue; //如果这个进程已经执行过,那么忽略 if(i == 1){flag = 1;break;}if(P[i].arrivetime <= P[pre].finishtime){ //如果已经到达if(P[i].runtime < minx){minx = P[i].runtime;flag = i; }}}if(m == 1) Output(flag,pre); else Calculate(flag,pre);P[flag].state = true; }ACTime(n,m);
}bool HRRN_cmp(Node a,Node b)
{if(a.arrivetime == b.arrivetime)return a.RR>b.RR; //返回响应比高的 return a.arrivetime < b.arrivetime;
}
int HRRN(int n,bool m)
{int flag=0; int T = n;while(T--){int pre = flag; sort(P+1,P+n+1,FCFS_cmp);double maxx = 0.0; //用来找最大响应比的进程for(int i=1;i<=n;++i){if(P[i].state==true) continue; if(i == 1){flag = 1;break;} if(P[i].arrivetime <= P[pre].finishtime){ Calculate(i,pre); //计算已经到达的响应比 if(m == 1)printf("P[%d]的响应比为:%.2lf\n",i,P[i].RR);if(P[i].RR > maxx){maxx = P[i].RR;flag = i; }}}if(m == 1) Output(flag,pre); else Calculate(flag,pre);P[flag].state = true; }ACTime(n,m);
}bool SP_cmp(Node a,Node b)
{if(a.arrivetime == b.arrivetime) return a.priority < b.priority; return a.arrivetime < b.arrivetime;
}
int SP(int n,bool m)
{int flag = 0;int T = n; while(T--){int pre = flag;sort(P+1,P+n+1,SJF_cmp);double minx = INF; //用来找优先权最小的进程for(int i=1;i<=n;++i){if(P[i].state==true) continue; if(i == 1){flag = 1;break;}if(P[i].arrivetime <= P[pre].finishtime){ if(P[i].priority < minx){minx = P[i].priority;flag = i; }}}if(m == 1) Output(flag,pre); else Calculate(flag,pre);P[flag].state = true; }ACTime(n,m);
}
//因为功能5要比较各个进程的周转时间,然而每运行一次某个算法
//进程的各属性值会改变,因此先保存一下输入的原内容,每次执行
//下一个算法时进行更新
void Update(int n)
{for(int i=1;i<=n;++i){P[i].name = rem[i].name;P[i].priority = rem[i].priority;P[i].arrivetime = rem[i].arrivetime;P[i].runtime = rem[i].runtime;P[i].state = false; }
}
//比较各个算法的平均周转时间
void CompareACT(int n)
{ cout<<"FCFS : ";FCFS(n,false);cout<<endl;Update(n);cout<<"SJF : ";SJF(n,false);cout<<endl;Update(n);cout<<"HRRN : ";HRRN(n,false);cout<<endl;Update(n);cout<<"SP : ";SP(n,false);cout<<endl;Update(n);ReturnMenu();
}
/*
a 5 1 5
b 3 2 3
c 4 2 4
d 1 6 6
e 2 8 2a 3 1 5
b 4 3 2
c 2 8 1
d 6 2 6
e 2 6 2
f 5 4 4a 3 2 6
b 2 1 3
c 4 6 2
d 1 10 1a 4 1.22 1.33
b 1 3.23 4.68
c 3 4.34 0.67
d 5 1.77 4.27
e 2 6.28 0.98
*/