CPU调度算法-Linux操作系统下的最高响应比优先(HRRN)调度算法-C语言(有代码)

        想象一下,你在一家餐厅里等待点餐。这家餐厅的服务员非常特别,他们决定谁先被服务不仅仅基于客人等待的时间,还基于客人的订单大小。如果一个客人点了很多食物,但等待的时间并不长,服务员可能会稍后为他服务。但如果这个客人等待了很长时间,即使他点的食物不多,服务员也会提高他的优先级,让他更快得到服务。

在这个比喻中:

  • 客人代表作业
  • 订单的大小代表作业的服务时间
  • 等待时间就是字面意义上的等待时间。
  • 服务员代表操作系统的调度器

        每个客人(作业)的“响应比”就像是他们的“饥饿指数”。这个指数是通过计算他们等待的时间和他们订单的大小来得出的。一个客人如果等待了很长时间或者他的订单很大,他的“饥饿指数”就会很高,因此服务员(调度器)会优先为他服务。

        这样,餐厅(操作系统)就能够确保每个客人都能在合理的时间内得到服务,没有人会因为点的食物少而等待太久,也没有人会因为点的食物多而被忽视。 

        最高响应比优先(HRRN)调度算法是一种计算机操作系统中的进程调度算法。它是介于先来先服务(FCFS)算法和最短作业优先(SJF)算法之间的一种折中方法。HRRN调度算法既考虑了作业的等待时间,也考虑了作业的服务时间,从而尝试公平地处理不同长度的作业。

调度规则如下:

        1.对每个作业计算其响应比,响应比的计算公式为:

        2.在每次调度时,选择响应比最高的作业进行服务。

优点

  • HRRN算法对于作业的时间分配比较均匀,既照顾了短作业,又不至于使长作业等待时间过长。

缺点

  • 每次计算响应比都会花费一定的时间,即时间开销。
  • 其性能比SJF算法略差。

这种算法通过动态地调整优先级,使得长作业在等待一定时间后,其优先级会逐渐提高,从而有机会被调度执行。这样,HRRN算法能够较好地平衡作业的等待时间和服务时间,改善系统的整体性能。

算法步骤:

1.任务数据结构设计:定义一个任务的数据结构,包括任务的到达时间、执行时间、优先级等信息。

2. 任务队列管理:维护一个任务队列,用于存储待执行的任务。

3. 计算响应比:对于每个待执行的任务,计算其响应比,响应比的计算公式为:响应比 = 1+ 等待时间/ 响应时间。

4. 选择下一个执行的任务:根据计算得到的响应比,选择具有最高响应比的任务作为下一个要执行的任务。

#include <stdio.h>
#define MAX_PROCESSES 10
typedef struct {
	int pid; // 进程 ID
	int arrival; // 到达时间
	int burst; // 执行时间
	int response; // 响应时间
	int waiting; // 等待时间
	int turnaround; // 周转时间
	float priority; // 优先级
} Process;

void calculatePriority(Process processes[], int n) {
	// 计算每个进程的响应比和优先级
	int i;
	for (i = 0; i < n; i++) {
		if (processes[i].response == 0) {
			processes[i].response = 1; // 避免除零错误
		}
		processes[i].priority = 1 + (float)processes[i].waiting /
		processes[i].response;
	}
}

void schedule(Process processes[], int n) {
	int total_waiting = 0;
	int total_turnaround = 0;
	// 计算每个进程的等待时间和周转时间
	int i;
	for (i = 0; i < n; i++) {
		total_waiting += processes[i].waiting;
		total_turnaround += processes[i].turnaround;
	}
	printf("Average Waiting Time: %.2f\n", (float) total_waiting / n);
	printf("Average Turnaround Time: %.2f\n", (float) total_turnaround / n);
}

int findNextProcess(Process processes[], int n, int currentTime) {
	int highestPriority = -1;
	int nextProcessIndex = -1;
	// 找到优先级最高的进程
	int i;
	for (i = 0; i < n; i++) {
		if (processes[i].arrival <= currentTime && processes[i].burst >0) {
			if (processes[i].priority > highestPriority) {
				highestPriority = processes[i].priority;
				nextProcessIndex = i;
			}
		}
	}
	return nextProcessIndex;
}

void execute(Process processes[], int n) {
	int currentTime = 0;
	int remainingProcesses = n;
	printf("Time\tPID\tWaiting\n");
	while (remainingProcesses > 0) {
		// 找到优先级最高的进程
		int nextProcessIndex = findNextProcess(processes, n,currentTime);
		if (nextProcessIndex == -1) {
			currentTime++; // 等待下一个进程到达
			continue;
		}
		// 执行进程
		Process *currentProcess = &processes[nextProcessIndex];
		currentProcess->waiting += currentTime - currentProcess->arrival;
		// 更新等待时间
		currentProcess->response = currentProcess->waiting + 1; // 更新响应时间
		currentProcess->burst--; // 执行一个时间单位
		currentTime++;
		printf("%d\t%d\t%d\n", currentTime, currentProcess->pid,currentProcess->waiting);
		// 如果进程执行完毕,则更新周转时间
		if (currentProcess->burst == 0) {
			currentProcess->turnaround = currentTime -
			currentProcess->arrival;
			remainingProcesses--;
		}
	}
}

int main() {
	Process processes[MAX_PROCESSES];
	int n;
	// 输入进程数量和每个进程的信息
	printf("Enter the number of processes: ");
	scanf("%d", &n);
	printf("Enter arrival time and burst time for each process:\n");
	int i;
	for (i = 0; i < n; i++) {
		printf("Process %d: ", i + 1);
		scanf("%d %d", &processes[i].arrival, &processes[i].burst);
		processes[i].pid = i + 1;
		processes[i].response = 0;
		processes[i].waiting = 0;
		processes[i].turnaround = 0;
	}
	// 计算响应比和优先级
	calculatePriority(processes, n);
	// 执行进程调度,并显示调度过程
	execute(processes, n);
	// 输出调度结果
	schedule(processes, n);
	return 0;
}

编译代码:将上述代码保存到一个.c文件中,例如hrrn.c。然后使用C编译器编译它。如果您使用的是GCC,可以在命令行中输入:

gcc -o hrrn hrrn.c

这将编译代码并生成一个名为hrrn的可执行文件。

运行程序:编译成功后,在命令行中运行可执行文件:

./hrrn

程序将提示您输入进程数量和每个进程的到达时间与执行时间。

输入数据:按照提示输入您想要模拟的进程数量(不超过10个),以及每个进程的到达时间和执行时间。例如:

Enter the number of processes: 3
Enter arrival time and burst time for each process:
Process 1: 0 5
Process 2: 2 3
Process 3: 4 1

这表示有3个进程,第一个进程在时间0到达,需要5个时间单位来完成;第二个进程在时间2到达,需要3个时间单位;第三个进程在时间4到达,只需要1个时间单位。

查看结果:输入完数据后,程序将模拟HRRN调度算法的执行过程,并输出每个时间单位的进程调度情况,以及最终的平均等待时间和平均周转时间。

请注意,这段代码是一个简单的模拟,主要用于教学和理解HRRN调度算法,并不适用于实际的操作系统调度。

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高响应比优先调度算法是一种非抢占式调度算法,它的目的是让优先级高、等待时间长的进程先执行。在单链表中实现最高响应比优先调度算法,可以按照以下步骤进行: 1. 定义进程结构体,包括进程ID、优先级、需要运行的时间、已经运行的时间等信息。 ```c typedef struct process { int pid; // 进程ID int priority; // 进程优先级 int need_time; // 进程需要运行的时间 int run_time; // 进程已经运行的时间 struct process *next; // 指向下一个进程的指针 } Process; ``` 2. 定义单链表结构体,包括头指针和尾指针。 ```c typedef struct process_list { Process *head; // 链表头指针 Process *tail; // 链表尾指针 } ProcessList; ``` 3. 定义创建进程的函数,根据输入的进程信息创建一个新的进程。 ```c Process *create_process(int pid, int priority, int need_time) { Process *p = (Process *)malloc(sizeof(Process)); p->pid = pid; p->priority = priority; p->need_time = need_time; p->run_time = 0; p->next = NULL; return p; } ``` 4. 定义插入进程的函数,将新的进程插入到单链表中。 ```c void insert_process(ProcessList *list, Process *p) { if (list->head == NULL) { // 如果链表为空 list->head = p; list->tail = p; } else { // 如果链表不为空 list->tail->next = p; list->tail = p; } } ``` 5. 定义计算响应比的函数,根据进程的优先级和等待时间计算响应比。 ```c float calculate_response_ratio(Process *p, int current_time) { return 1.0 + (current_time - p->run_time) / p->need_time; } ``` 6. 定义选择下一个要执行的进程的函数,遍历单链表,找到响应比最高的进程。 ```c Process *choose_next_process(ProcessList *list, int current_time) { Process *p = list->head; Process *chosen_process = NULL; float max_response_ratio = 0; while (p != NULL) { float response_ratio = calculate_response_ratio(p, current_time); if (response_ratio > max_response_ratio) { max_response_ratio = response_ratio; chosen_process = p; } p = p->next; } return chosen_process; } ``` 7. 定义执行进程的函数,将选择的进程执行一定时间,更新进程的运行时间。 ```c void run_process(Process *p, int time) { p->run_time += time; } ``` 8. 在主函数中,创建多个进程,插入到单链表中,按照最高响应比优先调度算法执行进程。 ```c int main() { ProcessList list = {NULL, NULL}; int current_time = 0; insert_process(&list, create_process(1, 3, 5)); insert_process(&list, create_process(2, 1, 3)); insert_process(&list, create_process(3, 2, 4)); while (list.head != NULL) { Process *p = choose_next_process(&list, current_time); int run_time = p->need_time - p->run_time; run_process(p, run_time); current_time += run_time; printf("Process %d runs for %d units of time.\n", p->pid, run_time); if (p->run_time == p->need_time) { printf("Process %d is finished.\n", p->pid); if (p == list.head) { list.head = p->next; } if (p == list.tail) { list.tail = NULL; } free(p); } } return 0; } ``` 以上就是在C语言中实现单链表最高响应比优先调度算法的基本步骤,你可以根据实际需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值