中断、时钟与轮转调度(Round-Robin)

本节目标

中断(Interrupt):硬件/时钟发信号给 CPU,CPU 暂停当前任务、跳去处理中断,处理完再回来。时钟中断是"多任务"的节拍器。

// 运行环境:Node.js 14+
// 保存为 aj-l12.js,执行:node aj-l12.js
class Scheduler {
  constructor(quantum = 2) {
    this.queue = []     // 就绪队列
    this.tick = 0
    this.quantum = quantum // 每个任务运行几个时钟周期
  }
  add(task) { this.queue.push({ name: task, used: 0 }) }
  // 时钟中断:每次 tick 推进,到时间片则抢占
  onClock() {
    if (!this.queue.length) return
    const cur = this.queue[0]
    cur.used++
    console.log(`tick ${this.tick}: 运行 ${cur.name} (${cur.used}/${this.quantum})`)
    this.tick++
    if (cur.used >= this.quantum) {
      cur.used = 0
      this.queue.shift()              // 出队
      this.queue.push(cur)            // 排到队尾(轮转)
      console.log(`  → 时间片到,${cur.name} 让出 CPU`)
    }
  }
}

// 调用示例:3 个任务轮流跑
const s = new Scheduler(2)
s.add('A'); s.add('B'); s.add('C')
for (let i = 0; i < 12; i++) s.onClock()

轮转(RR):每个任务跑一个固定时间片,时间到就排到队尾,下一个上。宏觉上"所有程序同时跑",实则是时钟中断在快速切换——单核 CPU 的"伪并行"。

名词解释

课后练习

  1. 如果没有时钟中断,单核能"同时"跑多个程序吗?
    • 答案:不能。没有时钟强制切换,一个程序不主动让出 CPU 就会一直占着,其他程序饿死;时钟中断是抢占式多任务的基石。
  2. RR 调度时间片设太长或太短分别有什么问题?
    • 答案:太长→响应慢、像批处理;太短→切换开销占比高、吞吐量下降。需按任务特性权衡。

总结

手写 RR 调度器,是把"多任务"从玄学变成可计算模型的一课。你会恍然大悟:所谓"电脑同时跑几十个程序",在单核上根本不是真并行,而是时钟中断这个"节拍器"在毫秒级快速切换,让每个程序都觉得自己独占 CPU。中断是这一切的总开关——没有它,一个死循环就能卡死全机。我特别想强调"时间片"这个权衡艺术:太长响应迟钝,太短切换耗尽算力。真实操作系统(Linux CFS、Windows)的调度比 RR 复杂得多,但"公平分配 CPU 时间 + 可抢占"的核心思想一脉相承。理解调度,你看任务管理器里每个进程"占用 CPU 百分比"、看 nice 值调优先级,就都知道背后是同一套"谁该上、上多久"的决策。这是从"会用电脑"到"懂电脑"的分水岭。