一、题目要求与概述
设计要求:编程实现一个作业模拟调度程序,计算不同调度算法下的作业平均周转周期及带权周转周期。
实现调度算法:1)先来先服务;2)短作业优先;3)最高响应比优先。
每个作业有一个作业控制块(JCB),主要包含信息:作业控制ID,作业名,作业达到时间,作业运行时间,作业完成时间,作业状态等。
设计内容:
1)作业数不得少于5个。
2)演示不同算法的调度过程。
3)计算不同算法下的作业平均周转周期及带权周转周期。
本实训以Windows为平台,以C语言为设计语言,进行操作系统各种算法的模拟实现。通过本实训,使学生掌握操作系统各个部分结构、实现机理及各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力。
二、算法流程图
(1)先来先服务算法
(2)短作业优先算法
(3)高响应比优先算法
三、代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <windows.h>
//函数声明
void test_data();
void sortarrivetime(struct PCB a[], int n);
void sortresponsetime(struct PCB a[], int start, int end);
void FCFS(struct PCB a[], int n);
void SJF(struct PCB a[], int n);
void HRN(struct PCB a[], int n);
void scanf_data();
void print_data();
int judge_id(int n);
//
//float t1; //总周转时间
//float t2; //总带权周转时间
float roundtime_sum; //总周转时间
float daiquantime_sum; //总带权周转时间
//float avr_t1; //平均周转时间
//float avr_t2; //平均带权周转时间
float avg_roundtime; //平均周转时间
float avg_daiquantime; //平均带权周转时间
int n;
struct PCB
{
int id; //作业id
char name[10]; //作业名
float arrivetime; //到达时间
float servetime; //运行时间
float finishtime; //完成时间
float roundtime; //周转时间
float daiquantime; //带权周转时间
float waittime; //等待时间
float responsebi;//响应比
int status; //作业状态
};
struct PCB a[50];//定义作业数组
//作业id重复返回0
int judge_id(int n)
{
for (int i = 0; i < n; i++)
{
if (a[i].id == a[n].id)
{
return 0;
}
}
return 1;
}
//按到达时间进行排序
void sortarrivetime(struct PCB a[], int n)
{
struct PCB t;
for (int i = 0; i < n - 1; i++)//控制轮数
{
for (int j = 0; j < n - 1 - i; j++)//控制比较次数
{
if (a[j].arrivetime > a[j + 1].arrivetime) //将到达时间短的交换到前边
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
}
//按响应比排序
void sortresponsetime(struct PCB a[], int start, int end) {
struct PCB t;
int n = end - start;
for (int i = 0; i < n; i++)
{
for (int j = start; j < end - i; j++)
{
if (a[j].responsebi < a[j + 1].responsebi) //将到达时间高的交换到前边
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
}
void print_data()
{
printf("=============================================================\n");
printf("作业相关信息如下:\n\n");
printf("作业id ");
printf("作业名 ");
printf("到达时间 ");
printf("服务时间 ");
printf("完成时间 ");
printf("周转时间 ");
printf("带权周转时间\n");
for (int i = 0; i < n; i++)
{
printf("%-10d", a[i].id);
printf("%-10s", a[i].name);
printf("%-10.0f", a[i].arrivetime);
printf("%-10.0f", a[i].servetime);
printf("%-10.0f", a[i].finishtime);
printf("%-10.0f", a[i].roundtime);
printf("%10.2f\n", a[i].daiquantime);
}
printf("\n");
printf("平均周转时间为:%2.2f\n", avg_roundtime);
printf("平均带权周转时间为:%2.2f\n", avg_daiquantime);
}
//先来先服务算法
void FCFS(struct PCB a[], int n)
{
int i;
a[0].finishtime = a[0].arrivetime + a[0].servetime; //完成时间=到达时间+服务时间
a[0].roundtime = a[0].finishtime - a[0].arrivetime; //周转时间=完成时间-到达时间
a[0].daiquantime = a[0].roundtime / a[0].servetime; //带权时间=周转时间/服务时间
a[0].status = 1;
for (i = 1; i < n; i++)
{
if (a[i].arrivetime < a[i - 1].finishtime)//当前到达时间在上一个作业结束时间之前
{
a[i].finishtime = a[i - 1].finishtime + a[i].servetime;//完成时间=上一个完成时间+服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; //周转时间=完成时间-到达时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; //带权时间=周转时间/服务时间
}
else //当前到达时间在上一个作业结束时间之后
{
a[i].finishtime = a[i].arrivetime + a[i].servetime; //完成时间=到达时间+服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; //周转时间=完成时间-到达时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; //带权时间=周转时间/服务时间
}
a[i].status = 1;
}
}
//短作业优先算法
void SJF(struct PCB a[], int n)
{
a[0].finishtime = a[0].arrivetime + a[0].servetime; //完成时间=到达时间+服务时间
a[0].roundtime = a[0].finishtime - a[0].arrivetime; //周转时间=完成时间-提交时间
a[0].daiquantime = a[0].roundtime / a[0].servetime; //带权时间=周转时间/服务时间
a[0].status = 1;
for (int i = 1; i < n; i++)
{
int min_serve = 999;//默认最小值
int index = i;//指向当前作业位置
//找最短服务时间
for (int j = i; j < n; j++)
{
//上一个作业的完成时间大于当前作业的到达时间
if (a[i - 1].finishtime > a[j].arrivetime && a[j].servetime < min_serve)
{
min_serve = a[j].servetime;
index = j;
}
}
//找到最短作业后交换位置
struct PCB temp;
temp = a[i];
a[i] = a[index];
a[index] = temp;
if (a[i].arrivetime < a[i - 1].finishtime) // 当前到达时间在上一个作业结束时间之前
{
a[i].finishtime = a[i - 1].finishtime + a[i].servetime; // 完成时间=上一个作业的完成时间+当前作业的服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; // 周转时间=完成时间-提交时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; // 带权时间=周转时间/服务时间
}
else // 当前到达时间在上一个作业结束时间之后
{
a[i].finishtime = a[i].arrivetime + a[i].servetime; // 完成时间=到达时间+服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; // 周转时间=完成时间-提交时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; // 带权时间=周转时间/服务时间
}
a[i].status = 1;
}
}
//最高响应比优先算法
void HRN(struct PCB a[], int n)
{
a[0].finishtime = a[0].arrivetime + a[0].servetime; //完成时间=到达时间+服务时间
a[0].roundtime = a[0].finishtime - a[0].arrivetime; //周转时间=完成时间-到达时间
a[0].daiquantime = a[0].roundtime / a[0].servetime; //带权时间=周转时间/服务时间
a[0].status = 1;
for (int i = 1; i < n; i++)//指向当前作业
{
for (int j = i; j < n; j++)//计算当前作业之后所有作业的响应比
{
a[j].waittime = a[i - 1].finishtime - a[j].arrivetime;//等待时间=上一个作业完成时间-当前作业到达时间
a[j].responsebi = (a[j].waittime + a[j].servetime) / a[j].servetime;//响应比
}
//按照响应比由大到小排序
sortresponsetime(a, i, n - 1);
if (a[i].arrivetime < a[i - 1].finishtime) // 当前到达时间在上一个作业结束时间之前
{
a[i].finishtime = a[i - 1].finishtime + a[i].servetime; // 完成时间=上一个作业的完成时间+当前作业的服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; // 周转时间=完成时间-提交时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; // 带权时间=周转时间/服务时间
}
else // 当前到达时间在上一个作业结束时间之后
{
a[i].finishtime = a[i].arrivetime + a[i].servetime; // 完成时间=到达时间+服务时间
a[i].roundtime = a[i].finishtime - a[i].arrivetime; // 周转时间=完成时间-提交时间
a[i].daiquantime = a[i].roundtime / a[i].servetime; // 带权时间=周转时间/服务时间
}
a[i].status = 1;
}
}
void scanf_data()
{
printf("请输入进程数:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
printf("%d 作业的id", i + 1);
scanf("%d", &a[i].id);
//作业id重复重新输入
while (!judge_id(i))
{
printf("作业的id重复请重新输入\n");
scanf("%d", &a[i].id);
}
printf("%d 作业名:", i + 1);
scanf("%s", a[i].name);
printf("作业到达时间:");
scanf("%f", &a[i].arrivetime);
printf("作业运行时间:");
scanf("%f", &a[i].servetime);
}
}
int main()
{
int select; //选择算法变量标识
scanf_data();//输入数据
while (1) //不试数为退出标识,保持循环
{
roundtime_sum = 0.0f;
daiquantime_sum = 0.0f;
printf("\n请选择算法:1.先来先服务算法 2.短作业优先算法 3.最高响应比优先算法 4.退出程序\n请输入选择: ");
scanf("%d", &select);
getchar();
if (select == 1) //先来先服务算法
{
printf("\n=====================先来先服务算法FCFS=====================\n\n");
sortarrivetime(a, n);//按到达时间先后进行冒泡排序
FCFS(a, n); //先来先服务算法
for (int i = 0; i < n; i++)
{
roundtime_sum += a[i].roundtime;
daiquantime_sum += a[i].daiquantime;
}
avg_roundtime = roundtime_sum / n;
avg_daiquantime = daiquantime_sum / n;
print_data();
}
else if (select == 2) //短作业优先算法
{
printf("\n=====================短作业优先算法FCFS=====================\n\n");
sortarrivetime(a, n);//按到达时间先后进行冒泡排序
SJF(a, n); //短作业优先算法
for (int i = 0; i < n; i++)
{
roundtime_sum += a[i].roundtime;
daiquantime_sum += a[i].daiquantime;
}
avg_roundtime = roundtime_sum / n;
avg_daiquantime = daiquantime_sum / n;
print_data();
}
else if (select == 3) //最高响应比优先算法
{
printf("\n=====================高响应比优先算法FCFS=====================\n\n");
sortarrivetime(a, n);//按到达时间先后进行冒泡排序
HRN(a, n); //高响应比优先算法
for (int i = 0; i < n; i++)
{
roundtime_sum += a[i].roundtime;
daiquantime_sum += a[i].daiquantime;
}
avg_roundtime = roundtime_sum / n;
avg_daiquantime = daiquantime_sum / n;
print_data();
}
else if (select == 4)
{
exit(0);
}
else
{
printf("please enter right choose!\n");
}
getchar(); // 等待用户按下回车键继续
system("cls"); // 清屏
}
return 0;
}