作为面试常用问题,单独列出一篇。
多个线程在竞争系统资源时,产生的一种僵持现象,无外力推动下,进程无法推进。这样的状态就是死锁。
死锁产生的原因
- 不可剥夺资源量少,不满足多进程推进,在运行过程中陷入僵局。可剥夺不会死锁。
- 进程推进时,线程请求和释放资源顺序不当。线程结束时才会释放资源,但提供给结束的资源被其他线程抢夺,导致全部等待。
死锁的必要产生条件
- 互斥条件:至少有一个资源处于非共享模式,即在线程同步状态下。
- 持有和等待条件:进程可以在持有自身资源的同时等待其他资源。(解锁条件不为单资源)
- 不剥夺条件:系统不能抢占已占有的资源,只能等线程释放。
- 循环等待条件:形成头尾相接的资源等待链,每个资源都在等待下一个线程的资源释放。
死锁的处理
死锁预防
破坏必要条件之一。
1.互斥:使所有资源能共享。
缺点:实际上有些资源只能互斥,有些资源需要互斥。
2.持有和等待:预先静态分配法,一次申请所有资源,未成功不运行,成功资源只属于此线程,不主动回收。
缺点:系统资源浪费,难以动态运行,复杂化,不利于共享,不适于复杂场景。
3.不剥夺:等待资源的进程请求不到资源时,释放所有资源重新申请。
4.循环等待:顺序资源分配法,对资源编号,预先定出资源分配顺序,按递增的ABC顺序申请,按CBA释放。
缺点:编号需相对稳定,难以添加新类型设备。需全局顺序定义编号。
避免死锁
动态分配资源时预测,防止系统进入不安全状态。
安全序列
如果能保证系统安全,也就是系统中的所有进程能够按照某一种次序分配资源,并且依次地运行完毕,那就不会出现死锁。而这种运行序列就是安全序列。
银行家算法
银行家算法会在每次请求资源时,模拟系统资源分配情况,检查分配后系统安全性,不安全则等待。用于实现安全序列生成和资源分配检查。
缺点:
1.静态资源分配假设,假设每个进程需要的最大资源量,动态的无法应对。
2.资源浪费,预留资源不运行。
3.复杂性,难以实现,难以维护更改。
4.顺序依赖,限制系统灵活性和并发性。
5.不适用动态环境,资源需求和释放可能是动态变化的。
死锁的检测及解除
允许死锁但能检测其发生,并有能力恢复。
死锁检测
资源分配图:
用长方形代表一个进程,用框代表一类资源。由于一种类型的资源可能有多个,用框中的一个点代表一类资源中的一个资源。从进程到资源的有向边叫请求边,表示该进程申请一个单位的该类资源;从资源到进程的边叫分配边,表示该类资源已经有一个资源被分配给了该进程。
先看资源是否剩余,再看进程可否满足,满足后消去所有关联边。
若所有边能完全去除,则该图可完全简化。
若不可完全简化,系统死锁。
死锁的解除
资源剥夺法
挂起死锁进程,抢占资源,分配给其他死锁进程。但应防止被挂起进程长期资源匮乏。
撤销进程法
强制撤销部分或全部死锁进程,剥夺资源。可按优先级和撤销代价考虑顺序。
进程回退法
回退一个或多个进程至回避死锁,释放资源。