Deadlock-循环等待
死锁是并发编程中最恶劣的 Bug 之一,因为它会导致系统静默冻结,而不是崩溃报错。
核心成因:四个必要条件 (Coffman Conditions)
虽然理论上有四条,但在 OS 内核开发中,最常触发的是循环等待 (Circular Wait)。
- 场景:
- CPU 0 持有锁 A,试图获取锁 B。
- CPU 1 持有锁 B,试图获取锁 A。
- 结果: 互相自旋,CPU 占用率 100% 但系统无响应。
另一个死锁陷阱:重入死锁 (Re-entrant Deadlock)
- 场景: 某个函数
func1获取了锁 A,然后调用func2。func2内部也试图获取锁 A。 - 结果: 自己等自己。
- xv6 机制: xv6 的自旋锁不支持重入。如果尝试获取一个自己已经持有的锁,内核会直接
panic: acquire。这是为了强迫程序员理清锁的所有权。
调试战术
死锁通常很难复现。如果系统卡死:
- GDB: 连接后随机中断,查看各 CPU 的栈回溯 (
bt)。如果大家都停在acquire的自旋循环里,那就是死锁。 - Lock Ordering: 检查代码是否违反了全局锁顺序。