操作系统-作业调度算法设计
作者:互联网
作业调度算法设计
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老师课程学生
标签:processes,操作系统,process,调度,int,算法,pa,time,select 来源: https://blog.csdn.net/Meet_Unknown/article/details/122020021