当前位置:首页 > C > 正文

C语言实现最短作业优先算法(SJF)详解:小白也能轻松掌握操作系统核心调度策略

在操作系统中,C语言最短作业优先算法(Shortest Job First, 简称 SJF)是一种经典的进程调度算法。它通过优先执行预计运行时间最短的作业,从而减少平均等待时间和平均周转时间。本教程将手把手教你用 C 语言实现 SJF 算法,即使你是编程小白,也能轻松理解并上手!

什么是“最短作业优先调度”?

最短作业优先调度(SJF)是一种非抢占式或抢占式的 CPU 调度算法。在非抢占式版本中,一旦一个进程开始执行,就会一直运行到完成;而在抢占式版本(也称为最短剩余时间优先 SRTF)中,如果新到达的进程比当前正在运行的进程剩余时间更短,系统会中断当前进程,转而执行新进程。

C语言实现最短作业优先算法(SJF)详解:小白也能轻松掌握操作系统核心调度策略 C语言最短作业优先算法 最短作业优先调度 C语言进程调度算法 操作系统作业调度 第1张

SJF 的优点与缺点

  • 优点:最小化平均等待时间,提高系统吞吐量。
  • 缺点:可能导致“饥饿”现象(长作业长时间得不到执行);实际中难以预知每个作业的确切运行时间。

用 C 语言实现非抢占式 SJF

下面我们用 C 语言编写一个简单的非抢占式 SJF 调度程序。假设我们有若干个进程,每个进程包含以下信息:

  • 进程 ID(pid)
  • 到达时间(arrival_time)
  • 执行时间(burst_time)

我们的目标是按 SJF 规则对这些进程进行排序并计算平均等待时间和平均周转时间。

完整代码示例

#include <stdio.h>#include <stdlib.h>typedef struct {    int pid;    int arrival_time;    int burst_time;    int waiting_time;    int turnaround_time;} Process;void swap(Process *a, Process *b) {    Process temp = *a;    *a = *b;    *b = temp;}void sortByBurstTime(Process processes[], int n) {    for (int i = 0; i < n - 1; i++) {        for (int j = 0; j < n - i - 1; j++) {            if (processes[j].burst_time > processes[j + 1].burst_time) {                swap(&processes[j], &processes[j + 1]);            }        }    }}int main() {    int n;    printf("请输入进程数量: ");    scanf("%d", &n);    Process *processes = (Process *)malloc(n * sizeof(Process));    for (int i = 0; i < n; i++) {        processes[i].pid = i + 1;        printf("输入进程 %d 的到达时间和执行时间: ", i + 1);        scanf("%d %d", &processes[i].arrival_time, &processes[i].burst_time);    }    // 按执行时间升序排序(SJF 核心)    sortByBurstTime(processes, n);    int current_time = 0;    float total_waiting = 0, total_turnaround = 0;    for (int i = 0; i < n; i++) {        // 如果当前时间小于到达时间,CPU 空闲        if (current_time < processes[i].arrival_time) {            current_time = processes[i].arrival_time;        }        processes[i].waiting_time = current_time - processes[i].arrival_time;        processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;        current_time += processes[i].burst_time;        total_waiting += processes[i].waiting_time;        total_turnaround += processes[i].turnaround_time;    }    printf("\n进程调度结果:\n");    printf("PID\t到达时间\t执行时间\t等待时间\t周转时间\n");    for (int i = 0; i < n; i++) {        printf("%d\t%d\t\t%d\t\t%d\t\t%d\n",               processes[i].pid,               processes[i].arrival_time,               processes[i].burst_time,               processes[i].waiting_time,               processes[i].turnaround_time);    }    printf("\n平均等待时间: %.2f\n", total_waiting / n);    printf("平均周转时间: %.2f\n", total_turnaround / n);    free(processes);    return 0;}  

代码说明

上述代码实现了非抢占式 SJF 调度:

  1. 首先定义 Process 结构体存储进程信息。
  2. 使用冒泡排序按 burst_time(执行时间)升序排列——这是 C语言进程调度算法中 SJF 的关键步骤。
  3. 依次计算每个进程的等待时间和周转时间,并更新当前系统时间。
  4. 最后输出调度结果和平均指标。

注意事项

在真实操作系统中,SJF 需要预测作业的执行时间,这通常通过历史数据估算。此外,为避免长作业“饥饿”,可结合老化(Aging)机制提升其优先级。

总结

通过本教程,你已经掌握了如何用 C 语言实现操作系统作业调度中的经典算法——最短作业优先(SJF)。它不仅是理解 CPU 调度的基础,也是面试和课程设计中的高频考点。动手运行上面的代码,修改输入数据,观察输出变化,你会对 SJF 有更深刻的理解!

关键词回顾:C语言最短作业优先算法最短作业优先调度C语言进程调度算法操作系统作业调度