引言

进程调度是操作系统中的核心模块,它决定了进程在处理器上的执行顺序和时间,从而影响了系统的性能和用户的体验。本文将深入浅出地解析操作系统中的进程调度算法,并通过C语言实战展示如何实现这些算法。

一、进程调度算法概述

1.1 基本概念

进程调度算法是指在进程等待执行时,根据一定的原则和策略,从就绪队列中选择一个或多个进程来占用处理器。常见的进程调度算法包括:

  • 先来先服务(FCFS)
  • 短作业优先(SJF)
  • 时间片轮转(RR)
  • 最高优先数(HPF)
  • 多级反馈队列(MFQ)

1.2 算法选择

选择合适的进程调度算法需要考虑以下因素:

  • 系统的响应时间
  • 系统的吞吐量
  • 系统的公平性
  • 系统的实时性

二、C语言实战解析

以下将展示如何使用C语言实现几种常见的进程调度算法。

2.1 先来先服务(FCFS)

#include <stdio.h>

#define MAXPROC 5

typedef struct {
    int id;
    int arrive;
    int burst;
} Process;

int main() {
    Process proc[MAXPROC] = {{1, 0, 3}, {2, 1, 6}, {3, 2, 4}, {4, 3, 5}, {5, 4, 2}};
    int waitingTime[MAXPROC];
    int turnaroundTime[MAXPROC];
    int completionTime[MAXPROC];
    int currentTime = 0;
    int i, j;

    // 初始化等待时间和完成时间
    for (i = 0; i < MAXPROC; i++) {
        waitingTime[i] = 0;
        turnaroundTime[i] = 0;
        completionTime[i] = 0;
    }

    // FCFS调度
    for (i = 0; i < MAXPROC; i++) {
        for (j = 0; j < i; j++) {
            if (proc[j].arrive < proc[i].arrive) {
                currentTime += proc[j].burst;
            }
        }
        waitingTime[i] = currentTime - proc[i].arrive;
        turnaroundTime[i] = waitingTime[i] + proc[i].burst;
        currentTime += proc[i].burst;
        completionTime[i] = currentTime;
    }

    // 输出结果
    printf("Process ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\tCompletion Time\n");
    for (i = 0; i < MAXPROC; i++) {
        printf("%d\t\t%d\t\t%d\t\t%d\t\t\t%d\t\t\t%d\n", proc[i].id, proc[i].arrive, proc[i].burst, waitingTime[i], turnaroundTime[i], completionTime[i]);
    }

    return 0;
}

2.2 短作业优先(SJF)

#include <stdio.h>

#define MAXPROC 5

typedef struct {
    int id;
    int arrive;
    int burst;
} Process;

int main() {
    Process proc[MAXPROC] = {{1, 0, 3}, {2, 1, 6}, {3, 2, 4}, {4, 3, 5}, {5, 4, 2}};
    int waitingTime[MAXPROC];
    int turnaroundTime[MAXPROC];
    int completionTime[MAXPROC];
    int i, j;

    // 初始化等待时间和完成时间
    for (i = 0; i < MAXPROC; i++) {
        waitingTime[i] = 0;
        turnaroundTime[i] = 0;
        completionTime[i] = 0;
    }

    // SJF调度
    for (i = 0; i < MAXPROC; i++) {
        int minIndex = i;
        for (j = i + 1; j < MAXPROC; j++) {
            if (proc[j].arrive <= currentTime && proc[j].burst < proc[minIndex].burst) {
                minIndex = j;
            }
        }
        waitingTime[i] = currentTime - proc[minIndex].arrive;
        turnaroundTime[i] = waitingTime[i] + proc[minIndex].burst;
        currentTime += proc[minIndex].burst;
        completionTime[i] = currentTime;
        proc[minIndex].arrive = currentTime;
        proc[minIndex].burst = 0;
    }

    // 输出结果
    printf("Process ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\tCompletion Time\n");
    for (i = 0; i < MAXPROC; i++) {
        printf("%d\t\t%d\t\t%d\t\t%d\t\t\t%d\t\t\t%d\n", proc[i].id, proc[i].arrive, proc[i].burst, waitingTime[i], turnaroundTime[i], completionTime[i]);
    }

    return 0;
}

2.3 时间片轮转(RR)

#include <stdio.h>

#define MAXPROC 5
#define QUANTUM 2

typedef struct {
    int id;
    int arrive;
    int burst;
} Process;

int main() {
    Process proc[MAXPROC] = {{1, 0, 7}, {2, 1, 5}, {3, 2, 3}, {4, 3, 9}, {5, 4, 6}};
    int waitingTime[MAXPROC];
    int turnaroundTime[MAXPROC];
    int completionTime[MAXPROC];
    int i, j;

    // 初始化等待时间和完成时间
    for (i = 0; i < MAXPROC; i++) {
        waitingTime[i] = 0;
        turnaroundTime[i] = 0;
        completionTime[i] = 0;
    }

    // RR调度
    for (i = 0; i < MAXPROC; i++) {
        if (proc[i].burst > QUANTUM) {
            waitingTime[i] = currentTime - proc[i].arrive;
            turnaroundTime[i] = waitingTime[i] + proc[i].burst;
            currentTime += proc[i].burst - QUANTUM;
            proc[i].burst = 0;
        } else {
            waitingTime[i] = currentTime - proc[i].arrive;
            turnaroundTime[i] = waitingTime[i] + proc[i].burst;
            currentTime += proc[i].burst;
            proc[i].burst = 0;
        }
        completionTime[i] = currentTime;
    }

    // 输出结果
    printf("Process ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\tCompletion Time\n");
    for (i = 0; i < MAXPROC; i++) {
        printf("%d\t\t%d\t\t%d\t\t%d\t\t\t%d\t\t\t%d\n", proc[i].id, proc[i].arrive, proc[i].burst, waitingTime[i], turnaroundTime[i], completionTime[i]);
    }

    return 0;
}

2.4 最高优先数(HPF)

#include <stdio.h>

#define MAXPROC 5

typedef struct {
    int id;
    int arrive;
    int burst;
    int priority;
} Process;

int main() {
    Process proc[MAXPROC] = {{1, 0, 3, 5}, {2, 1, 6, 2}, {3, 2, 4, 1}, {4, 3, 5, 3}, {5, 4, 2, 4}};
    int waitingTime[MAXPROC];
    int turnaroundTime[MAXPROC];
    int completionTime[MAXPROC];
    int i, j;

    // 初始化等待时间和完成时间
    for (i = 0; i < MAXPROC; i++) {
        waitingTime[i] = 0;
        turnaroundTime[i] = 0;
        completionTime[i] = 0;
    }

    // HPF调度
    for (i = 0; i < MAXPROC; i++) {
        int maxIndex = i;
        for (j = i + 1; j < MAXPROC; j++) {
            if (proc[j].priority > proc[maxIndex].priority && proc[j].arrive <= currentTime) {
                maxIndex = j;
            }
        }
        waitingTime[i] = currentTime - proc[maxIndex].arrive;
        turnaroundTime[i] = waitingTime[i] + proc[maxIndex].burst;
        currentTime += proc[maxIndex].burst;
        completionTime[i] = currentTime;
        proc[maxIndex].arrive = currentTime;
        proc[maxIndex].burst = 0;
    }

    // 输出结果
    printf("Process ID\tArrival Time\tBurst Time\tPriority\tWaiting Time\tTurnaround Time\tCompletion Time\n");
    for (i = 0; i < MAXPROC; i++) {
        printf("%d\t\t%d\t\t%d\t\t%d\t\t\t%d\t\t\t%d\t\t\t%d\n", proc[i].id, proc[i].arrive, proc[i].burst, proc[i].priority, waitingTime[i], turnaroundTime[i], completionTime[i]);
    }

    return 0;
}

2.5 多级反馈队列(MFQ)

#include <stdio.h>

#define MAXPROC 5
#define MAXLEVEL 3

typedef struct {
    int id;
    int arrive;
    int burst;
    int priority;
} Process;

int main() {
    Process proc[MAXPROC] = {{1, 0, 7, 5}, {2, 1, 5, 2}, {3, 2, 3, 1}, {4, 3, 9, 3}, {5, 4, 6, 4}};
    int waitingTime[MAXPROC];
    int turnaroundTime[MAXPROC];
    int completionTime[MAXPROC];
    int i, j;

    // 初始化等待时间和完成时间
    for (i = 0; i < MAXPROC; i++) {
        waitingTime[i] = 0;
        turnaroundTime[i] = 0;
        completionTime[i] = 0;
    }

    // MFQ调度
    for (i = 0; i < MAXPROC; i++) {
        int level = 0;
        while (level < MAXLEVEL) {
            int index = -1;
            int timeSlice = 1 << level; // 时间片
            for (j = 0; j < MAXPROC; j++) {
                if (proc[j].priority == level && proc[j].arrive <= currentTime) {
                    index = j;
                    break;
                }
            }
            if (index == -1) {
                level++;
                continue;
            }
            if (proc[index].burst > timeSlice) {
                waitingTime[i] = currentTime - proc[index].arrive;
                turnaroundTime[i] = waitingTime[i] + proc[index].burst;
                currentTime += timeSlice;
                proc[index].burst -= timeSlice;
                if (proc[index].burst <= timeSlice) {
                    level++;
                }
            } else {
                waitingTime[i] = currentTime - proc[index].arrive;
                turnaroundTime[i] = waitingTime[i] + proc[index].burst;
                currentTime += proc[index].burst;
                proc[index].burst = 0;
            }
            completionTime[i] = currentTime;
            proc[index].priority++;
        }
    }

    // 输出结果
    printf("Process ID\tArrival Time\tBurst Time\tPriority\tWaiting Time\tTurnaround Time\tCompletion Time\n");
    for (i = 0; i < MAXPROC; i++) {
        printf("%d\t\t%d\t\t%d\t\t%d\t\t\t%d\t\t\t%d\t\t\t%d\n", proc[i].id, proc[i].arrive, proc[i].burst, proc[i].priority, waitingTime[i], turnaroundTime[i], completionTime[i]);
    }

    return 0;
}

三、总结

本文深入浅出地解析了操作系统中的进程调度算法,并通过C语言实战展示了如何实现这些算法。通过对不同算法的比较和分析,我们可以更好地理解各种算法的优缺点,为实际应用选择合适的调度策略。