动态高优先权优先进程调度

一、实验目的

目的:了解并掌握动态高优先权优先调度算法的理论,掌握动态优先权的设置方式。

任务:模拟实现动态高优先权优先的调度(若数值越大优先权越高,每运行一个时间单位优先权-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; // 恢复优先级(你可以根据需求选择如何处理优先级)
		}
	}
}

四、实验结果

输入:

输出:

相关推荐
中屹指纹浏览器5 分钟前
2026多账号安全运营:指纹浏览器选型、部署与平台风控应对指南
经验分享·笔记
条tiao条32 分钟前
从 “Top-K 问题” 入门二叉堆:C 语言从零实现与经典应用
c语言·算法·深度优先
高梦轩34 分钟前
LNMP 环境部署笔记
linux·笔记
角砾岩队长1 小时前
CASS常用快捷指令
经验分享·笔记
云边散步1 小时前
godot2D游戏教程系列二(14)
笔记·学习·游戏·游戏开发
1231566802 小时前
PAT 1017 A除以B
c语言·数据结构·算法·pat考试
崔高杰2 小时前
训练数据选择又有新方法了?——两篇文章的阅读笔记 Less is Enough和 OPUS
人工智能·笔记·机器学习
爱吃奶酪的松鼠丶2 小时前
LangGraph 实战笔记:用 AI 发起流程应用
人工智能·笔记
小付同学呀2 小时前
C语言学习(九)——C判断三元运算符
c语言·开发语言·学习
Z9fish2 小时前
sse哈工大C语言编程练习42
c语言·开发语言·算法