想象一下,你在一家餐厅里等待点餐。这家餐厅的服务员非常特别,他们决定谁先被服务不仅仅基于客人等待的时间,还基于客人的订单大小。如果一个客人点了很多食物,但等待的时间并不长,服务员可能会稍后为他服务。但如果这个客人等待了很长时间,即使他点的食物不多,服务员也会提高他的优先级,让他更快得到服务。
在这个比喻中:
- 客人代表作业。
- 订单的大小代表作业的服务时间。
- 等待时间就是字面意义上的等待时间。
- 服务员代表操作系统的调度器。
每个客人(作业)的“响应比”就像是他们的“饥饿指数”。这个指数是通过计算他们等待的时间和他们订单的大小来得出的。一个客人如果等待了很长时间或者他的订单很大,他的“饥饿指数”就会很高,因此服务员(调度器)会优先为他服务。
这样,餐厅(操作系统)就能够确保每个客人都能在合理的时间内得到服务,没有人会因为点的食物少而等待太久,也没有人会因为点的食物多而被忽视。
最高响应比优先(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调度算法,并不适用于实际的操作系统调度。