Deadlock-循环等待

死锁是并发编程中最恶劣的 Bug 之一,因为它会导致系统静默冻结,而不是崩溃报错。

核心成因:四个必要条件 (Coffman Conditions)

虽然理论上有四条,但在 OS 内核开发中,最常触发的是循环等待 (Circular Wait)

  • 场景:
    • CPU 0 持有锁 A,试图获取锁 B。
    • CPU 1 持有锁 B,试图获取锁 A。
    • 结果: 互相自旋,CPU 占用率 100% 但系统无响应。

另一个死锁陷阱:重入死锁 (Re-entrant Deadlock)

  • 场景: 某个函数 func1 获取了锁 A,然后调用 func2func2 内部也试图获取锁 A。
  • 结果: 自己等自己。
  • xv6 机制: xv6 的自旋锁不支持重入。如果尝试获取一个自己已经持有的锁,内核会直接 panic: acquire。这是为了强迫程序员理清锁的所有权。

调试战术

死锁通常很难复现。如果系统卡死:

  1. GDB: 连接后随机中断,查看各 CPU 的栈回溯 (bt)。如果大家都停在 acquire 的自旋循环里,那就是死锁。
  2. Lock Ordering: 检查代码是否违反了全局锁顺序。