p-》lock的传递性

这是本章最反直觉的设计:锁的获取和释放跨越了线程边界。

危机场景

  1. 进程 A 在 yield() 中将状态设为 RUNNABLE
  2. 进程 A 准备调用 swtch,但还没切走(还在 A 的栈上)。
  3. 如果此时没有锁: 另一个 CPU 的调度器看到了 A 是 RUNNABLE,决定运行 A。
  4. 灾难: 两个 CPU 同时运行进程 A(同一个栈)。栈崩溃,数据错乱。

解决方案

  1. A 拿锁: A 在 yield() 开始时获取 p->lock
  2. A 带着锁切换: A 调用 swtch不释放锁
  3. Scheduler 运行: 切换到 Scheduler 线程。此时 p->lock 依然是被锁住的(尽管 CPU 换了,栈换了)。
  4. Scheduler 放锁: Scheduler 确认 A 已经彻底切走了,才调用 release(&p->lock)

总结: A 锁门,Scheduler 拔钥匙。这保证了“A 在切换期间,绝对不会被其他 CPU 选中”。