69天探索操作系统-第38天:CPU 调度

## 1. 介绍 CPU调度是现代操作系统的关键组成部分,确保高效地分配资源和进行进程管理。它涉及复杂的算法,这些算法决定了进程执行的顺序,并平衡优先级、公平性和实时约束等因素。这些算法旨在优化CPU利用率,减少等待时间,并确保关键任务的及时执行。

高级CPU调度中的关键概念包括多级队列管理基于优先级的调度抢占机和负载平衡。多级队列允许进程被分类到不同的优先级级别,每个级别都有其自己的调度算法。基于优先级的调度确保高优先级任务首先执行,而实时调度则保证时间敏感任务能够满足其截止时间。这些技术对于构建迅速且高效的操作系统至关重要。

2.多级队列实现

2.1 多级队列调度

多级队列调度根据优先级或其他标准将进程划分为多个队列。每个队列可以有自己的调度算法,例如轮转调度或先到先服务(FCFS)。高优先级队列中的进程先于低优先级队列中的进程执行。这种方法通常用于操作系统,以处理交互式、批处理和实时进程的混合情况。

以下代码演示了一个多级队列的实现:

C 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAX_QUEUES 5
#define MAX_PROCESSES 100

typedef struct Process {
    int pid;
    int priority;
    int burst_time;
    int remaining_time;
    int arrival_time;
    int waiting_time;
    int turnaround_time;
} Process;

typedef struct Queue {
    Process *processes;
    int front;
    int rear;
    int size;
    int time_quantum;
    int priority_level;
} Queue;

typedef struct MultiLevelQueue {
    Queue queues[MAX_QUEUES];
    int num_queues;
} MultiLevelQueue;

void init_queue(Queue *q, int priority_level, int time_quantum) {
    q->processes = (Process*)malloc(MAX_PROCESSES * sizeof(Process));
    q->front = q->rear = -1;
    q->size = 0;
    q->priority_level = priority_level;
    q->time_quantum = time_quantum;
}

bool is_queue_empty(Queue *q) {
    return q->size == 0;
}

void enqueue(Queue *q, Process p) {
    if (q->size == MAX_PROCESSES) return;

    if (q->front == -1) {
        q->front = 0;
    }

    q->rear = (q->rear + 1) % MAX_PROCESSES;
    q->processes[q->rear] = p;
    q->size++;
}

Process dequeue(Queue *q) {
    Process p = q->processes[q->front];

    if (q->front == q->rear) {
        q->front = q->rear = -1;
    } else {
        q->front = (q->front + 1) % MAX_PROCESSES;
    }

    q->size--;
    return p;
}

MultiLevelQueue* init_multilevel_queue(int num_queues) {
    MultiLevelQueue *mlq = (MultiLevelQueue*)malloc(sizeof(MultiLevelQueue));
    mlq->num_queues = num_queues;

    for (int i = 0; i < num_queues; i++) {
        init_queue(&mlq->queues[i], i, (i + 1) * 2);
    }

    return mlq;
}

void schedule_processes(MultiLevelQueue *mlq) {
    int current_time = 0;
    bool all_queues_empty;

    do {
        all_queues_empty = true;

        for (int i = 0; i < mlq->num_queues; i++) {
            Queue *current_queue = &mlq->queues[i];

            if (!is_queue_empty(current_queue)) {
                all_queues_empty = false;
                Process current_process = dequeue(current_queue);

                int execution_time = (current_queue->time_quantum < current_process.remaining_time)
                                   ? current_queue->time_quantum
                                   : current_process.remaining_time;
                current_process.remaining_time -= execution_time;
                current_time += execution_time;

                if (current_process.remaining_time > 0) {
                    if (i < mlq->num_queues - 1) {
                        enqueue(&mlq->queues[i + 1], current_process);
                    } else {
                        enqueue(current_queue, current_process);
                    }
                } else {
                    current_process.turnaround_time = current_time - current_process.arrival_time;
                    current_process.waiting_time = current_process.turnaround_time - current_process.burst_time;

                    printf("Process %d completed. Turnaround Time: %d, Waiting Time: %d\n",
                           current_process.pid,
                           current_process.turnaround_time,
                           current_process.waiting_time);
                }
            }
        }
    } while (!all_queues_empty);
}

运行代码

shell 复制代码
gcc -o multilevel_queue multilevel_queue.c
./multilevel_queue

3. 基于优先级的调度

3.1 优先级调度算法

优先调度为每个进程分配一个优先级,优先级最高的进程先执行。该算法有助于确保关键任务得到及时处理。以下代码使用最小堆实现了一个基于优先级的调度器:

C 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct {
    int pid;
    int priority;
    int burst_time;
    int remaining_time;
    bool is_active;
} PriorityProcess;

typedef struct {
    PriorityProcess *processes;
    int capacity;
    int size;
} PriorityQueue;

PriorityQueue* init_priority_queue(int capacity) {
    PriorityQueue *pq = (PriorityQueue*)malloc(sizeof(PriorityQueue));
    pq->processes = (PriorityProcess*)malloc(capacity * sizeof(PriorityProcess));
    pq->capacity = capacity;
    pq->size = 0;
    return pq;
}

void heapify(PriorityQueue *pq, int idx) {
    int smallest = idx;
    int left = 2 * idx + 1;
    int right = 2 * idx + 2;

    if (left < pq->size &&
        pq->processes[left].priority < pq->processes[smallest].priority) {
        smallest = left;
    }

    if (right < pq->size &&
        pq->processes[right].priority < pq->processes[smallest].priority) {
        smallest = right;
    }

    if (smallest != idx) {
        PriorityProcess temp = pq->processes[idx];
        pq->processes[idx] = pq->processes[smallest];
        pq->processes[smallest] = temp;
        heapify(pq, smallest);
    }
}

void insert_process(PriorityQueue *pq, PriorityProcess process) {
    if (pq->size == pq->capacity) return;

    pq->processes[pq->size] = process;

    int current = pq->size;
    while (current > 0 &&
           pq->processes[(current - 1) / 2].priority >
           pq->processes[current].priority) {
        PriorityProcess temp = pq->processes[(current - 1) / 2];
        pq->processes[(current - 1) / 2] = pq->processes[current];
        pq->processes[current] = temp;
        current = (current - 1) / 2;
    }

    pq->size++;
}

PriorityProcess extract_min(PriorityQueue *pq) {
    if (pq->size <= 0) {
        PriorityProcess empty = {0, 0, 0, 0, false};
        return empty;
    }

    PriorityProcess root = pq->processes[0];
    pq->processes[0] = pq->processes[pq->size - 1];
    pq->size--;

    heapify(pq, 0);
    return root;
}

void priority_schedule(PriorityQueue *pq) {
    int current_time = 0;
    int completed = 0;

    while (completed < pq->size) {
        PriorityProcess current = extract_min(pq);

        if (current.is_active) {
            printf("Time %d: Executing process %d (Priority: %d)\n",
                   current_time, current.pid, current.priority);

            current.remaining_time--;
            current_time++;

            if (current.remaining_time > 0) {
                insert_process(pq, current);
            } else {
                completed++;
                printf("Process %d completed at time %d\n",
                       current.pid, current_time);
            }
        }
    }
}

运行代码:

shell 复制代码
gcc -o priority_scheduler priority_scheduler.c
./priority_scheduler

4. 实时调度

4.1 最早截止时间优先(EDF)调度

实时调度确保时间敏感任务能够按时完成。最早截止时间优先(EDF)算法首先调度截止时间最近的进程。以下代码展示了EDF调度:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>

typedef struct {
    int pid;
    int period;
    int execution_time;
    int deadline;
    int next_deadline;
    bool is_periodic;
} RTProcess;

typedef struct {
    RTProcess *processes;
    int size;
    int capacity;
} RTScheduler;

RTScheduler* init_rt_scheduler(int capacity) {
    RTScheduler *rts = (RTScheduler*)malloc(sizeof(RTScheduler));
    rts->processes = (RTProcess*)malloc(capacity * sizeof(RTProcess));
    rts->capacity = capacity;
    rts->size = 0;
    return rts;
}

bool edf_schedule(RTScheduler *rts, int simulation_time) {
    int current_time = 0;

    while (current_time < simulation_time) {
        int earliest_deadline_idx = -1;
        int min_deadline = INT_MAX;

        for (int i = 0; i < rts->size; i++) {
            if (rts->processes[i].next_deadline < min_deadline &&
                rts->processes[i].execution_time > 0) {
                min_deadline = rts->processes[i].next_deadline;
                earliest_deadline_idx = i;
            }
        }

        if (earliest_deadline_idx != -1) {
            RTProcess *current = &rts->processes[earliest_deadline_idx];

            printf("Time %d: Executing process %d (Deadline: %d)\n",
                   current_time, current->pid, current->next_deadline);

            current->execution_time--;
            current_time++;

            if (current_time > current->next_deadline) {
                printf("Deadline missed for process %d\n", current->pid);
                return false;
            }

            if (current->execution_time == 0 && current->is_periodic) {
                current->execution_time = current->period;
                current->next_deadline += current->period;
            }
        } else {
            current_time++;
        }
    }

    return true;
}

运行代码:

shell 复制代码
gcc -o realtime_scheduler realtime_scheduler.c
./realtime_scheduler

5. 性能分析

性能分析涉及计算平均等待时间、周转时间、CPU 利用率和吞吐量等指标。以下代码演示了如何计算这些指标:

c 复制代码
typedef struct {
    double avg_waiting_time;
    double avg_turnaround_time;
    double cpu_utilization;
    double throughput;
    int context_switches;
} SchedulerMetrics;

SchedulerMetrics calculate_metrics(Process *processes, int n, int total_time) {
    SchedulerMetrics metrics = {0};
    int total_waiting_time = 0;
    int total_turnaround_time = 0;

    for (int i = 0; i < n; i++) {
        total_waiting_time += processes[i].waiting_time;
        total_turnaround_time += processes[i].turnaround_time;
    }

    metrics.avg_waiting_time = (double)total_waiting_time / n;
    metrics.avg_turnaround_time = (double)total_turnaround_time / n;
    metrics.cpu_utilization = ((double)total_time - metrics.avg_waiting_time) /
                             total_time * 100;
    metrics.throughput = (double)n / total_time;

    return metrics;
}

运行代码:

shell 复制代码
gcc -o scheduler_metrics scheduler_metrics.c
./scheduler_metrics

6. 总结

高级CPU调度对于优化现代操作系统的进程执行至关重要。通过理解和实施多级队列、基于优先级的调度和实时调度,开发人员可以构建高效且响应迅速的系统。提供的代码示例展示了这些概念的实际方法,使您能够分析和改进调度性能。

相关推荐
胡尔摩斯.7 小时前
LoadBalancer负载均衡服务调用
java·后端·spring cloud·loadbalancer
编程|诗人7 小时前
T-SQL语言的数据库交互
开发语言·后端·golang
IT筱筱8 小时前
springboot集成websocket实现实时大量数据,效率性能高
spring boot·后端·websocket
coding侠客9 小时前
线上工单引发的思考:Spring Boot 中 @Autowired 与 @Resource 的区别
java·spring boot·后端
vip1024p9 小时前
springboot集成onlyoffice(部署+开发)
java·spring boot·后端
秃了也弱了。10 小时前
springboot使用websocket
spring boot·后端·websocket
计算机-秋大田10 小时前
基于微信小程序教学辅助系统设计与实现(LW+源码+讲解)
java·后端·微信小程序·小程序·课程设计
web1828599708910 小时前
【SpringBoot】深度解析 Spring Boot 拦截器:实现统一功能处理的关键路径
java·spring boot·后端
塞尔维亚大汉10 小时前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(一)
操作系统·harmonyos
web1309332039811 小时前
什么是Spring Boot 应用开发?
java·spring boot·后端