操作系统-作业调度算法设计
2021/12/20 17:29:23
本文主要是介绍操作系统-作业调度算法设计,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
作业调度算法设计
1.先来先服务调度算法(实现)
2.短作业优先调度算法(实现,但可能有漏洞)
3.最高响应比调度算法(实现,但可能有漏洞)
4.最短剩余时间调度算法(抢占式,实现,但可能有漏洞)
输入
数据存放于 data.txt 文件中,每列分别对应进程名、进程到达时间、进程运行时间:
J1 8:00 30.0 J2 8:20 5.0 J3 8:30 15.0
代码详情
#define _CRT_SECURE_NO_WARNINGS #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char pname[10]; // 进程名 = input float pid; // 进程id = input char arrival[10]; // 到达时刻 = input float time_arrival; // 到达时间 = time2int(arrival) float time_run; // 运行时间 = input 单位:分钟 float time_start; // 开始时间 According to the reslut of the algorithm float time_finish; // 完成时间 According to the reslut of the algorithm float time_remaining; // 剩余时间 char begin[10]; // 开始时刻 = "str(time_start/60):str(time_start%60)" use ecvt() or gcvt(). char finish[10]; // 完成时刻 = "str(time_finish/60):str(time_finish%60)" float tar; // 周转时间 Turnaround time = time_finish - ta float tarw; // 带权周转时间 Turnaround time with weight = tar / tr float rp; // 响应比 } process; typedef struct { int len; float ava_tar, ava_tarw; // 平均周转时间、平均带权周转时间 process *processes; } process_array; void print_process_array(process_array *pa) { printf("====================================================\ ==================================================================\n"); printf("\t进程名\t到达时间\t运行时间\t开始时间\t完成时间\t周转时间\t带权周转时间\n"); for (int i = 0; i < pa->len; i++) { printf("----------------------------------------------------\ ------------------------------------------------------------------\n"); printf("\t %s\t %s\t\t %-.2f\t\t %s\t\t %s\t\t %-.2f\t\t %-.2f\n", pa->processes[i].pname, pa->processes[i].arrival, pa->processes[i].time_run, pa->processes[i].begin, pa->processes[i].finish, pa->processes[i].tar, pa->processes[i].tarw); } printf("----------------------------------------------------\ ------------------------------------------------------------------\n"); printf("\t平均周转时间:\t\t\t\t\t\t\t\t %.2f\n", pa->ava_tar); printf("----------------------------------------------------\ ------------------------------------------------------------------\n"); printf("\t平均带权周转时间:\t\t\t\t\t\t\t\t\t %.2f\n", pa->ava_tarw); printf("====================================================\ ==================================================================\n"); } // 释放内存 void free_process_array(process_array **pa) { free((*pa)->processes); free(*pa); *pa = NULL; } int time2int(char *time) { // 输入形如:xx:xx 格式的时间,输出分钟型的时间 int len_char = sizeof(time); char t[10]; for (int i = 0; i < len_char; i++) { t[i] = time[i]; } char min[4]; for (int i = 0; i < len_char; i++) { if (time[i] == ':') { int k = 0; while (time[k + i + 1] != '\0') { min[k] = time[k + i + 1]; k++; } min[k] = '\0'; break; } } char *hour = strtok(t, ":"); return atol(hour) * 60 + atol(min); // 字符型转整型 } char *int2time(int time, char *buf) { int hour = (time / 60) % 24; int minute = time % 60; if (sprintf(buf, "%02d:%02d", hour, minute) < 0) return NULL; return buf; } // 初始化参数 void process_init(process_array *pa) { for (int i = 0; i < pa->len; i++) { pa->processes[i].time_arrival = time2int(pa->processes[i].arrival); pa->processes[i].time_remaining = pa->processes[i].time_run; pa->processes[i].time_start = -1; // 代表进程未开始运行 pa->processes[i].tar = -1; // 代表周转时间未计算 pa->processes[i].tarw = -1; // 代表带权周转时间未计算 pa->processes[i].rp = -1; // 代表响应比未计算 } } // 到达时间排序,先到先排 void sort_by_arrive_time(process_array *pa) { for (int i = 0; i < pa->len; i++) { for (int j = i + 1; j < pa->len; j++) { if (pa->processes[j].time_arrival < pa->processes[i].time_arrival) { process tmp = pa->processes[i]; pa->processes[i] = pa->processes[j]; pa->processes[j] = tmp; } } } } // 短作业优先 void shortest_job_first(process_array *pa) { float current_time = -1; // -1 表示未初始化 for (int i = 0; i < pa->len; i++) { if (current_time == -1) { current_time = pa->processes[i].time_arrival; } // 选择当前时刻内最短的作业 int select = 0; for (int j = 0; j < pa->len; j++) { if (pa->processes[j].time_finish != 0) { continue; // 作业已经完成 } if (pa->processes[j].time_arrival > current_time) { break; // 时间没到 } if (pa->processes[j].time_run < pa->processes[select].time_run) { select = j; } } // 执行选择的任务 pa->processes[select].time_start = current_time; int2time(pa->processes[select].time_start, pa->processes[select].begin); pa->processes[select].time_finish = pa->processes[select].time_start + pa->processes[select].time_run; int2time(pa->processes[select].time_finish, pa->processes[select].finish); pa->processes[select].tar = pa->processes[select].time_finish - pa->processes[select].time_arrival; pa->processes[select].tarw = pa->processes[select].tar / pa->processes[select].time_run; current_time = pa->processes[select].time_finish; } } // 响应比计算 float response_ratio(process process, int start_time) { /* 响应比 = ((开始运行时间 - 作业到达时间) + 运行时间) / 运行时间 */ return ((start_time - process.time_arrival) + process.time_run) / process.time_run; } // 最高响应比优先 // 用于作业/进程调度 // 非抢占式的算法,因此只有当前运行的作业/进程主动放弃处理器时,才需要调度,才需要计算响应比 void highest_response_ratio_priority(process_array *pa, char* start) { int work_time = time2int(start); float max_rp; for (int m = 0; m < pa->len; m++) { max_rp = 0; int i = 0; // 统计有多少个作业/进程在某次调度开始前到达 for (int n = 0; n < pa->len; n++) { if (pa->processes[n].time_arrival <= work_time) { if (pa->processes[n].rp != 0) { // 计算这些作业的响应比,找出最大的 pa->processes[n].rp = response_ratio(pa->processes[n], work_time); if (pa->processes[n].rp > max_rp) { max_rp = pa->processes[n].rp; i = n; } continue; } } else break; } // 响应比最大的开始运行 pa->processes[i].time_start = work_time; int2time(pa->processes[i].time_start, pa->processes[i].begin); pa->processes[i].time_finish = pa->processes[i].time_start + pa->processes[i].time_run; int2time(pa->processes[i].time_finish, pa->processes[i].finish); pa->processes[i].tar = pa->processes[i].time_finish - pa->processes[i].time_arrival; pa->processes[i].tarw = pa->processes[i].tar / pa->processes[i].time_run; work_time = pa->processes[i].time_finish; // 下一次进行作业调度时间为当前作业运行完成时刻 pa->processes[i].rp = 0; // 完成作业 } } // 先来先服务 void first_come_first_service(process_array *pa) { float current_time = -1; // -1 表示未初始化 for (int i = 0; i < pa->len; i++) { if (current_time == -1) { current_time = pa->processes[i].time_arrival; } pa->processes[i].time_start = current_time; int2time(pa->processes[i].time_start, pa->processes[i].begin); // 转成字符串 pa->processes[i].time_finish = pa->processes[i].time_start + pa->processes[i].time_run; int2time(pa->processes[i].time_finish, pa->processes[i].finish); pa->processes[i].tar = pa->processes[i].time_finish - pa->processes[i].time_arrival; pa->processes[i].tarw = pa->processes[i].tar / pa->processes[i].time_run; current_time = pa->processes[i].time_finish; } } // 最短剩余优先(抢占式) void shortest_residue_time_fist(process_array *pa) { int curren_time = 0; curren_time = pa->processes[0].time_arrival; while (1) { int break_flag = 1; for (int i = 0; i < pa->len; i++) { if (pa->processes[i].time_remaining != 0) { break_flag = 0; } } if (break_flag == 1) { break; } // 找出最短剩余时间的进程 int select = 0; for (int i = 0; i < pa->len; i++) { if (curren_time < pa->processes[i].time_arrival) { break; } if (pa->processes[i].time_remaining == 0) { continue; } if (pa->processes[i].time_remaining < pa->processes[select].time_remaining || pa->processes[select].time_remaining == 0) { select = i; break; } } // 抢占运行 if (pa->processes[select].time_start == -1) { pa->processes[select].time_start = curren_time; int2time(pa->processes[select].time_start, pa->processes[select].begin); // 转成字符串 } pa->processes[select].time_remaining--; curren_time++; if (pa->processes[select].time_remaining == 0) { pa->processes[select].time_finish = curren_time; int2time(pa->processes[select].time_finish, pa->processes[select].finish); // 转成字符串 pa->processes[select].tar = pa->processes[select].time_finish - pa->processes[select].time_arrival; pa->processes[select].tarw = (float)pa->processes[select].tar / pa->processes[select].time_run; } } } // 求平均周转时间、平均带权周转时间 void compute_average(process_array *pa) { float sum_tar = 0, sum_tarw = 0; for (int i = 0; i < pa->len; i++) { sum_tar += pa->processes[i].tar; sum_tarw += pa->processes[i].tarw; } pa->ava_tar = sum_tar / pa->len; pa->ava_tarw = sum_tarw / pa->len; } // 从文件中读取初始数据 process_array *read_process_array_from_file(const char *path) { FILE *fp = fopen(path, "r"); if (fp == NULL) { return NULL; } // 申请一个进程队列空间 process_array *pa = calloc(sizeof(process_array), 1); char line[256]; while (fgets(line, sizeof(line), fp) != NULL) { pa->len += 1; process *tmp = calloc(sizeof(process), pa->len); memcpy(tmp, pa->processes, sizeof(*tmp) * (pa->len - 1)); free(pa->processes); pa->processes = tmp; // 分别读入进程名、进程到达时间、进程运行时间 if (sscanf(line, "%s %s %f", pa->processes[pa->len - 1].pname, pa->processes[pa->len - 1].arrival, &pa->processes[pa->len - 1].time_run) != 3) { free(tmp); } } fp = NULL; return pa; } int run() { process_array *pa = read_process_array_from_file("data.txt"); if (pa == NULL) { printf("%s\n", strerror(errno)); return 1; } // 初始化各参数 process_init(pa); // 根据到达时间排序 sort_by_arrive_time(pa); int algorithm; printf("====================================================\ ==================================================================\n\ ==============================================数据已载入,请选择算法===\ ===============================================\n\ \t1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序\n"); printf("====================================================\ ==================================================================\n"); scanf("%d", &algorithm); system("cls"); printf("====================================================\ ==================================================================\n"); switch (algorithm) { case 1: printf("\t\t\t\t\t先来先服务调度算法\n"); first_come_first_service(pa); break; case 2: printf("\t\t\t\t\t短作业优先调度算法\n"); shortest_job_first(pa); break; case 3: printf("\t\t\t\t\t最高响应比调度算法\n"); printf("\t请输入开始时间:"); char* start[10]; scanf("%s", &start); printf("\n"); highest_response_ratio_priority(pa, start); break; case 4: printf("\t\t\t\t\t最短剩余时间调度算法\n"); shortest_residue_time_fist(pa); break; case 5: return 1; break; default: printf("您的选择不在范围内,请从以下算法中选择:\n"); // 释放内存 free_process_array(&pa); return 0; break; } compute_average(pa); print_process_array(pa); // 释放内存 free_process_array(&pa); return 0; } int main() { while (1) { if(run() == 1) break; } return 0; }
输出
选择算法界面
====================================================================================================================== ==============================================数据已载入,请选择算法================================================== 1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序 ======================================================================================================================
结果显示界面
====================================================================================================================== 最短剩余时间调度算法 ====================================================================================================================== 进程名 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间 ---------------------------------------------------------------------------------------------------------------------- J1 8:00 30.00 08:00 08:35 35.00 1.17 ---------------------------------------------------------------------------------------------------------------------- J2 8:20 5.00 08:20 08:25 5.00 1.00 ---------------------------------------------------------------------------------------------------------------------- J3 8:30 15.00 08:35 08:50 20.00 1.33 ---------------------------------------------------------------------------------------------------------------------- 平均周转时间: 20.00 ---------------------------------------------------------------------------------------------------------------------- 平均带权周转时间: 1.17 ====================================================================================================================== ====================================================================================================================== ==============================================数据已载入,请选择算法================================================== 1.先来先服务调度算法, 2.短作业优先调度算法, 3.最高响应比调度算法, 4.最短剩余时间调度算法, 5.退出程序 ======================================================================================================================
19 guan老师课程学生
这篇关于操作系统-作业调度算法设计的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法