好几天没写博客了,刚好在写操作系统的实验作业,所以就想着分享一下,当然,鉴于博主的代码能力以及学的不咋滴的操作系统,所以代码可能会有点搓,大家担待哈,如果有错误也还请大佬斧正!
目录
题目一 作业调度
一、实验目的
二、实验内容及要求
三,代码实现
3.1,algorithm.h
3.2,algorithm.c
3.3,test.c
1、 对作业调度的相关内容作进一步的理解。
2、 明白作业调度的主要任务。
3、 通过编程掌握作业调度的主要算法。
编程模拟实现单道批处理系统作业调度:
1、对于给定的一组作业,给出其到达时间和运行时间,例如下表所示:
作业名 A B C D E F
到达时间(ms) 0 2 5 5 12 15
服务时间(ms) 6 50 20 10 40 8
2、每个作业用一个作业控制块JCB来代表,作业控制块的结构包括:作业名、到达时间、服务时间、开始时间、完成时间、周转时间、带权周转时间、链接指针等。
3、分别用先来先服务算法、短作业优先和响应比高者优先三种调度算法进行调度,显示逐次被选中作业的作业名以及作业后备队列的变化。调度全部完成后显示所有作业的作业名、到达时间、服务时间、开始时间、完成时间、周转时间、带权周转时间的列表。注意此程序是模拟作业调度,被选中的作业并不实际启动运行,只是改变相关数据。
4、计算每一种算法的平均周转时间及平均带权周转时间并比较不同算法的优劣。
题目已给出所有作业的到达时间以及运行时间,所以初始数据我们是从文件中导入到程序中。
算法头文件,主要是用来进行各种函数以及类型的声明
#pragma once
#include
#include
#include
#include
#include
//声明一个作业JCB类型的结构体,用来对应相关数据
struct JOB {
char homname;
int arrtime;//到达时间
int sertime;//服务时间
int strtime;//开始时间
int fintime;//完成时间
int wattime;//周转时间
float tatime;//带权周转时间
};//定义一个结构体数组,来存放每一个作业的JCB信息;
//声明读文件函数
int readfile();
//声明FCFS函数
void FCFS(ret);
//声明SJF函数
void SJF(ret);
//声明HRRN函数
void HRRN(ret);
算法源文件,主要是调度算法的功能实现板块,包含各种函数的定义。
#define _CRT_SECURE_NO_WARNINGS 1
#include "algorithm.h"
extern struct JOB job[20];//声明一下这个全局变量
//定义读文件函数
int readfile() {
//打开文件
FILE* pf = fopen("info.txt", "r");
if (pf == NULL) {
perror("readfile::fopen");
return;
}
//读文件
//循环读取文件
int i = 0;
printf("作业名 作业到达时间 作业运行所需要时间\n");
while (!feof(pf)) {//feof 如果文件已经是因为到了文件末尾而结束了,就会返回非0值
int ch = 0;
fscanf(pf, "%c%d%d", &job[i].homname, &(job[i].arrtime), &(job[i].sertime));
printf("%3c%12d%15d\n", job[i].homname, job[i].arrtime, job[i].sertime);
getc(pf);//吃掉每行后面的换行符
i++;
}
printf("\n");
//关闭文件
fclose(pf);
pf = NULL;
return i;
}
//定义FCFS函数
void FCFS(ret) {
struct JOB job1[20] = { 0 };
memmove(job1, job, sizeof(job));
for (int i = 0;i < ret;i++) {
printf("现在正在调用 %c 作业\n", job1[i].homname);
if (i < ret - 1) {
printf("此时后被队列为:");
}
else {
printf("后备队列为空!\n");
}
for (int j = i + 1;j < ret;j++) {
printf("%c ", job1[j].homname);
}
printf("\n");
}
printf("调度完成,整体调度各个阶段时间详细过程如下:\n");
for (int i = 0;i < ret;i++) {
//计算完成时间
if (i == 0) {
job1[i].fintime = job1[i].arrtime + job1[i].sertime;
}
else {
job1[i].fintime = job1[i - 1].fintime + 1 + job1[i].sertime;
}
//计算开始时间
if (i == 0) {
job1[0].strtime = 0;
}
else {
job1[i].strtime = job1[i - 1].fintime + 1;
}
//计算周转时间
job1[i].wattime = job1[i].fintime - job1[i].arrtime;
//计算带权周转时间
job1[i].tatime = (float)job1[i].wattime / job1[i].sertime;
}
//输出展示
printf("作业名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
for (int i = 0;i < ret;i++) {
printf("%3c%12d%12d%12d%12d%12d%12.2f\n", job1[i].homname, job1[i].arrtime, job1[i].sertime, job1[i].strtime, job1[i].fintime, job1[i].wattime, job1[i].tatime);
}
int allwattime = 0;//周转时间之和
float alltatime = 0;//带权周转时间之和
for (int i = 0; i < ret; i++) {
allwattime += job1[i].wattime;
alltatime += job1[i].tatime;
}
printf("\n平均作业周转时间:%0.2f ms", (float)allwattime / ret);
printf("\n平均作业带权周转时间:%0.2f ms\n", alltatime / ret);
printf("\n");
}
//定义SJF函数
void SJF(ret) {
struct JOB job2[20] = {0};
memmove(job2, job, sizeof(job));
for (int i = 0;i < ret;i++) {
//进来先检查相邻两个作业的到达时间是不是一样的,如果是一样的,就需要进行服务时间的比较了
if (job2[i].arrtime == job2[i + 1].arrtime) {
if (job2[i].sertime > job2[i + 1].sertime) {
struct JOB tmp = job2[i];
job2[i] = job2[i + 1];
job2[i + 1] = tmp;
}
}
//计算完成时间
if (i == 0) {
job2[i].fintime = job2[i].arrtime + job2[i].sertime;
}
else {
job2[i].fintime = job2[i - 1].fintime + 1 + job2[i].sertime;
}
//计算开始时间
if (i == 0) {
job2[0].strtime = 0;
}
else {
job2[i].strtime = job2[i - 1].fintime + 1;
}
//计算周转时间
job2[i].wattime = job2[i].fintime - job2[i].arrtime;
//计算带权周转时间
job2[i].tatime = (float)job2[i].wattime / job2[i].sertime;
}
for (int i = 0;i < ret;i++) {
printf("现在正在调用 %c 作业\n", job2[i].homname);
if (i < ret - 1) {
printf("此时后被队列为:");
}
else {
printf("后备队列为空!\n");
}
for (int j = i + 1;j < ret;j++) {
printf("%c ", job2[j].homname);
}
printf("\n");
}
printf("调度完成,整体调度各个阶段时间详细过程如下:\n");
//输出展示
printf("作业名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
for (int i = 0;i < ret;i++) {
printf("%3c%12d%12d%12d%12d%12d%12.2f\n", job2[i].homname, job2[i].arrtime, job2[i].sertime, job2[i].strtime, job2[i].fintime, job2[i].wattime, job2[i].tatime);
}
int allwattime = 0;//周转时间之和
float alltatime = 0;//带权周转时间之和
for (int i = 0; i < ret; i++) {
allwattime += job2[i].wattime;
alltatime += job2[i].tatime;
}
printf("\n平均作业周转时间:%0.2f ms", (float)allwattime / ret);
printf("\n平均作业带权周转时间:%0.2f ms\n", alltatime / ret);
printf("\n");
}
//定义HRRN函数
void HRRN(ret) {
struct JOB job3[20] = { 0 };
memmove(job3, job, sizeof(job));
int a = ret-1;
int past = 0;
for (int i = 0;i < ret;i++) {
//计算响应比,以最后一个作业的完成时间作为标准
float Responseratio[6] = { 0 };
float max = 0;
for (int j = 0;j < ret;j++) {
if (job3[j].strtime == 0) {
if (i == 0) {
Responseratio[j] = (job3[a].arrtime - job3[j].arrtime + job3[j].sertime) / (float)job3[j].sertime;
}
else {
Responseratio[j] = (job3[a].fintime - job3[j].arrtime + job3[j].sertime) / (float)job3[j].sertime;
}
}
if (Responseratio[j] > max) {
max = Responseratio[j];
}
}
for (int j = 0;j < ret;j++) {
if (max == Responseratio[j]) {
a = j;
}
}
//响应比最高的开始执行
int tmp = a;
if (i == 0) {
job3[tmp].strtime = job3[ret - 1].arrtime + 1;
}
else {
job3[tmp].strtime = job3[past].fintime + 1;
}
job3[tmp].fintime = job3[tmp].strtime + job3[tmp].sertime;
//计算周转时间
job3[tmp].wattime = job3[tmp].fintime - job3[tmp].arrtime;
//计算带权周转时间
job3[tmp].tatime = (float)job3[tmp].wattime / job3[tmp].sertime;
past = a;
printf("现在正在调度 %c 作业\n", job3[a].homname);
if (i < ret - 1) {
printf("此时后被队列为:");
}
else {
printf("后备队列为空!\n");
}
for (int j = 0;j < ret;j++) {
if (job3[j].strtime == 0) {
printf("%c ", job3[j].homname);
}
}
printf("\n");
}
printf("调度完成,整体调度各个阶段时间详细过程如下:\n");
//输出展示
printf("作业名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
for (int i = 0;i < ret;i++) {
printf("%3c%12d%12d%12d%12d%12d%12.2f\n", job3[i].homname, job3[i].arrtime, job3[i].sertime, job3[i].strtime, job3[i].fintime, job3[i].wattime, job3[i].tatime);
}
int allwattime = 0;//周转时间之和
float alltatime = 0;//带权周转时间之和
for (int i = 0; i < ret; i++) {
allwattime += job3[i].wattime;
alltatime += job3[i].tatime;
}
printf("\n平均作业周转时间:%0.2f ms", (float)allwattime / ret);
printf("\n平均作业带权周转时间:%0.2f ms\n", alltatime / ret);
printf("\n");
}
主函数框架的实现主体,main函数所在,进行函数的调度。
#define _CRT_SECURE_NO_WARNINGS 1
#include "algorithm.h"
void menu() {
printf("===== 调度算法选择 =====\n");
printf("===== 1,先来先服务(FCFS) =====\n");
printf("===== 2,短作业优先(SJF ) =====\n");
printf("===== 3,高响应比算法(HRRN) =====\n");
printf("===== 0,退出系统 =====\n");
}
struct JOB job[20] = { 0 };
int main() {
int ret = readfile();
int input = 0;
do {
menu();
printf("请进行算法的选择>>\n");
scanf("%d", &input);
switch (input) {
case 1:
FCFS(ret);
Sleep(10000);//停滞三秒
system("cls");
break;
case 2:
SJF(ret);
Sleep(10000);//停滞三秒
system("cls");
break;
case 3:
HRRN(ret);
Sleep(10000);//停滞三秒
system("cls");
break;
case 0:
printf("退出系统!\n");
break;
default:
printf("选择错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
感谢大家的阅读哦,如果觉得不错的话,还请帮忙点点赞哦,十分感谢!