课程设计:
结构体:struct Node,定义进程的信息
菜单算法:int Select,选择菜单,可以多次使用程序选择不同算法
输入算法:int Input,实现手动输入进程信息和利用in.txt文件输入进程信息。
计算算法:int Calculate,计算进程的各个属性,到达时间、等待时间、完成时间、周转时间、响应比。
用文件输入可以在该文件夹里新建一个in.txt的文本,保存测试用例,这样子就可以实现以文件的形式输入进程。
#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;
}
return 0;
}
//选择菜单
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 << " 请输入选择的序号: ";
return 0;
}
//输入内容
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; //那么等待时间为0
P[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; //计算响应比
return 0;
}
//输出内容
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);
return 0;
}
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);
return 0;
}
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);
return 0;
}
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);
return 0;
}
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);
return 0;
}
//因为功能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 2
*/
代码转载与博主Learning_is_endless
链接:(27条消息) 操作系统课程设计:仿真通用处理机调度_处理机调度仿真_Learning_is_endless的博客-CSDN博客
更改了部分代码,让代码可以在Visual Studio中成功运行,谢谢这位博主提供的内容,让我受益匪浅。