一、实验目的
目的:了解并掌握动态高优先权优先调度算法的理论,掌握动态优先权的设置方式。
任务:模拟实现动态高优先权优先的调度(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,每运行一个时间单位优先权+n)。
二、实验内容
设置进程体:进程名,进程的到达时间,服务时间,初始优先权,进程状态(W------等待,R------运行,F------完成),进程间的链接指针;
进程初始化:由用户输入进程名、服务时间、初始优先权进行初始化,同时,初始化进程的状态为W;
显示函数:在进程调度前、调度中和调度后进行显示;
排序函数:对就绪状态的进程按照优先权排序。优先权相同时进入等待队列时间早的进程在前,注意考虑到达时间;
调度函数:每次从等待队列队首调度优先权最高的进程执行,状态变化。并在执行一个时间单位后优先权变化,服务时间变化,状态变化。当服务时间为0时,状态变为F。
删除函数:撤销状态为F的进程。
三、实验代码
cs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for sleep function
#define MAX_PROCESSES 100 // 最大进程数量
typedef struct {
char name[20]; // 进程名称
int arrival_time; // 到达时间
int service_time; // 服务时间
int priority; // 优先级
int remaining_time; // 剩余时间
int completion_time; // 完成时间
int turnaround_time; // 周转时间
float weighted_turnaround_time; // 带权周转时间
char state; // 状态: W(等待), R(运行), F(完成)
} Process;
Process processList[MAX_PROCESSES];
int processCount = 0;
int currentTime = 0; // 当前时间
// 函数声明
void inputProcesses();
void sortProcesses();
void runScheduler();
void printSummary();
void printProcessesStatus(); // 打印所有进程状态
void undoCompletedProcesses(); // 撤销状态为F的进程
int main() {
inputProcesses();
runScheduler();
printSummary();
undoCompletedProcesses(); // 撤销状态为F的进程
return 0;
}
// 输入进程信息
void inputProcesses() {
printf("请输入进程数量: ");
scanf("%d", &processCount);
for (int i = 0; i < processCount; i++) {
printf("请输入第 %d 个进程的信息:\n", i + 1);
printf("进程名称: ");
scanf("%s", processList[i].name);
printf("到达时间: ");
scanf("%d", &processList[i].arrival_time);
printf("服务时间: ");
scanf("%d", &processList[i].service_time);
printf("优先级: ");
scanf("%d", &processList[i].priority);
// 初始化
processList[i].remaining_time = processList[i].service_time;
processList[i].completion_time = 0;
processList[i].turnaround_time = 0;
processList[i].weighted_turnaround_time = 0.0;
processList[i].state = 'W'; // 初始状态为等待
}
}
// 按优先级排序已到达的进程
void sortProcesses() {
for (int i = 0; i < processCount - 1; i++) {
for (int j = 0; j < processCount - i - 1; j++) {
if (processList[j].arrival_time <= currentTime &&
processList[j + 1].arrival_time <= currentTime &&
processList[j].priority < processList[j + 1].priority) {
// 交换进程
Process temp = processList[j];
processList[j] = processList[j + 1];
processList[j + 1] = temp;
}
}
}
}
// 打印所有进程当前状态
void printProcessesStatus() {
printf("\n当前进程状态:\n");
printf("名称\t状态\t剩余时间\t优先级\n");
printf("-------------------------------------------\n");
for (int i = 0; i < processCount; i++) {
printf("%s\t%c\t%d\t\t%d\n",
processList[i].name,
processList[i].state,
processList[i].remaining_time,
processList[i].priority);
}
printf("-------------------------------------------\n");
}
// 运行调度程序
void runScheduler() {
while (1) {
sortProcesses(); // 每次时间推进前排序
int allCompleted = 1; // 检查所有进程是否完成
int found = 0; // 记录是否找到可调度进程
printProcessesStatus(); // 调度前,打印所有进程状态
for (int i = 0; i < processCount; i++) {
if (processList[i].state != 'F' && processList[i].arrival_time <= currentTime) {
found = 1; // 找到可调度进程
allCompleted = 0; // 有未完成的进程
// 设置状态为运行
processList[i].state = 'R';
printf("时间 %d: 调度进程 %s,优先级 %d\n", currentTime, processList[i].name, processList[i].priority);
// 执行一个时间单位
processList[i].remaining_time--;
sleep(1); // 模拟时间单位
// 检查是否完成
if (processList[i].remaining_time == 0) {
processList[i].state = 'F'; // 完成
processList[i].completion_time = currentTime + 1; // 记录完成时间
printf("时间 %d: 进程 %s 已完成\n", currentTime + 1, processList[i].name);
} else {
// 当服务时间不为0时,优先级减2,状态改为等待
processList[i].priority -= 2;
processList[i].state = 'W'; // 状态改为等待
}
printProcessesStatus(); // 打印所有进程状态
break; // 每次调度一次进程
}
}
if (allCompleted) { // 如果所有进程都完成
break;
}
currentTime++; // 时间步进
}
}
// 打印总结信息
void printSummary() {
printf("\n进程的执行结果:\n");
printf("名称\t完成时间\t周转时间\t带权周转时间\n");
for (int i = 0; i < processCount; i++) {
if (processList[i].state == 'F') {
processList[i].turnaround_time = processList[i].completion_time - processList[i].arrival_time;
processList[i].weighted_turnaround_time = (float)processList[i].turnaround_time / processList[i].service_time;
printf("%s\t%d\t\t%d\t\t%.2f\n",
processList[i].name,
processList[i].completion_time,
processList[i].turnaround_time,
processList[i].weighted_turnaround_time);
}
}
}
// 撤销状态为F的进程
void undoCompletedProcesses() {
for (int i = 0; i < processCount; i++) {
if (processList[i].state == 'F') {
printf("撤销进程 %s 的完成状态。\n", processList[i].name);
// 重新初始化进程的状态
processList[i].state = 'W';
processList[i].remaining_time = processList[i].service_time; // 恢复剩余时间
processList[i].completion_time = 0;
processList[i].turnaround_time = 0;
processList[i].weighted_turnaround_time = 0.0;
processList[i].priority += 2; // 恢复优先级(你可以根据需求选择如何处理优先级)
}
}
}
四、实验结果
输入:
输出: