死锁是操作系统中一种特定的状态,其中两个或多个进程被永远阻塞,因为每个进程都在等待另一个进程所持有的资源。只有当以下四个条件同时存在时,死锁才会发生:互斥、占有并等待、不可抢占和循环等待。例如,P1 持有 R1 并需要 R2,而 P2 持有 R2 并需要 R1,导致两者无限期等待。我们可以通过预防、避免(如银行家算法)或检测与恢复来处理死锁。
操作系统中的死锁是如何发生的?
在操作系统中,一个进程通常按以下顺序使用资源:
- 请求资源
- 使用资源
- 释放资源
当进程持有一些资源的同时,又在等待其他资源时,死锁就产生了。
示例:
- 进程 P1 持有资源 R1 并请求 R2。
- 进程 P2 持有资源 R2 并请求 R1。
两个进程都无法继续执行,从而导致死锁。
!d
死锁的示例
关于死锁有几种不同的场景。其中一些示例如下。
1. 系统有 2 个磁带驱动器。P0 和 P1 各自持有一个磁带驱动器,且各自都需要另一个。
2. 信号量 A 和 B 初始化为 1,P0 和 P1 进入了如下死锁状态:
- P0 执行 wait(A) 并被抢占。
- P1 执行 wait(B)。
- 此时 P0 和 P1 进入死锁。
P1 动作
—
wait(B)
wait(A)3. 假设可用分配空间为 200K 字节,发生了以下事件序列:
P1
—
请求 70KB;
请求 80KB;如果两个进程都推进到它们的第二次请求,就会发生死锁。
操作系统中产生死锁的必要条件
如果以下四个条件同时满足(必要条件),死锁就会发生:
- 互斥: 在任何给定时间,只有一个进程能使用一个资源,即资源是不可共享的。
- 占有并等待: 一个进程至少持有一个资源,同时正在等待获取被其他进程持有的额外资源。
- 不可抢占: 除非进程主动释放资源,否则不能强行从该进程中拿走资源。
- 循环等待: 一组进程以循环的方式互相等待。例如,想象四个进程 P1、 P2、 P3 和 P4 以及四个资源 R1、 R2、 R3 和 R4。
!Circular wait example上面的图展示了一个循环等待死锁,具体情况如下:
- P1 正持有 R1 并等待 R2(由 P2 持有)。
- P2 正持有 R2 并等待 R3(由 P3 持有)。
- P3 正持有 R3 并等待 R4(由 P4 持有)。
- P4 正持有 R4 并等待 R1(由 P1 持有)。