若将执行顺序换成红字的顺序:
Producer:
- 执行
P(mutex)
mutex 1->0
- 执行
P(empty)
empty 0->-1
阻塞
Consumer: - 执行
P(mutex)
mutex 0->-1
,阻塞
Producer 脱离阻塞需要先执行Consumer: V(empty)
,在执行之前又依赖于P(full)
,P(full)
的执行需要 Consumer 脱离阻塞,Consumer 脱离阻塞需要执行Producer: V(mutex)
,执行Producer: V(mutex)
需要 Producer 脱离阻塞.
形成一种环路,造成死锁。
死锁:多个进程由于互相等待对方持有的资源而造成都无法执行的情况。
死锁的处理方法:
死锁预防:
例:预防火灾
破坏死锁出现的条件
- 在进程执行前,一次性申请所有需要的资源,不会占有资源再去申请其他资源。缺点:1. 需要预知未来,变成困难 2. 许多资源分配后很长时间后才使用,资源利用率低
- 对资源类型进行排序,资源申请必须按序进行,不会出现环路等待。缺点:仍然造成资源浪费。
死锁避免:
例:检测到煤气超标,自动切断电源
检测每个资源请求,如果造成死锁就拒绝
银行家算法:
占有资源(Allocation),需求资源(Need),可分配资源(Available)
首先Avaliable(2,3,0),可以执行P1,执行完毕释放资源后,Avaliable(2+3,3+0,0+2),可以执行P3,执行完毕释放资源Avaliable(5+2,3+1,2+1),以此类推。
最后执行序列为 A选项
实现:
缺点:每次申请都执行银行家算法
O
(
m
n
2
)
O(mn^2)
O(mn2),效率太低
死锁检测+恢复:
例:出现火灾,拿起灭火器
检测到死锁出现时,让进程释放资源,回滚状态
缺点:回滚实现困难。
死锁忽略:
例:在太阳上可以对火灾全然不顾
假装没有死锁
死锁出现的条件不是确定的,又可以用重启动处理死锁。
在大多数非专门的操作系统都使用,如Unix,Linux 和 Windows 中都没有死锁处理