任务调度 - 练习题

练习 1:调度统计

记录每个进程的调度统计信息:

typedef struct {
    uint32_t context_switches;  // 被调度次数
    uint32_t total_ticks;       // 获得的总tick数
    uint32_t cpu_percent;       // CPU占用百分比
} sched_stats_t;

实现 scheduler_dump_stats() 打印所有进程的调度统计。

练习 2:优先级调度

修改轮转调度器支持优先级:

  • 高优先级进程获得更大的时间片
  • 实现多级就绪队列(每个优先级一个队列)
#define NUM_PRIORITIES 4
static process_t *ready_queues[NUM_PRIORITIES];
 
void schedule(void) {
    // 从最高优先级队列开始查找就绪进程
    for (int p = 0; p < NUM_PRIORITIES; p++) {
        if (ready_queues[p]) {
            // 调度这个进程
        }
    }
}

练习 3:sleep系统调用

实现进程休眠功能:

void process_sleep(uint32_t milliseconds) {
    current->wake_tick = ticks + ms_to_ticks(milliseconds);
    current->state = PROCESS_BLOCKED;
    schedule();
}

在定时器中断中检查是否有进程需要唤醒。

练习 4:yield系统调用

实现主动让出CPU:

void task_cooperative(void) {
    while (1) {
        do_work();
        scheduler_yield();  // 主动让出
    }
}

练习 5:进程创建演示

实现一个交互式Shell,通过键盘命令创建和管理进程:

  • run <name> - 创建新进程
  • kill <pid> - 终止进程
  • ps - 列出所有进程
  • top - 显示CPU占用

思考题

  1. Round-Robin公平吗?什么场景下不公平?
  2. 如果时间片设得太短(如1ms)会怎样?太长(如1秒)呢?
  3. 实时操作系统的调度器有什么特殊要求?
  4. CFS(完全公平调度器)是如何工作的?与RR有何不同?