死锁相关知识

219 阅读3分钟

死锁就是两个线程互相争夺占有的资源,谁也不肯放手,造成都无法正常运行

死锁四个必要条件:

互斥条件,不可剥夺条件,请求与保持条件,循环等待条件

1、互斥

对分配的资源进行排他性控制,其他资源如果申请该线程资源,只能等待。

2、不可剥夺

进程所有的资源在自己没主动释放之前,别的人不能剥夺。

3、请求与保持

如果进程请求新的资源,一时无法获得,自己现有的资源不放手。

4、循环等待

进程提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放

死锁的解决

预防死锁、避免死锁、检测死锁、解除死锁

1、预防死锁

主要方式就是打破死锁的四个必要条件之一就可以,但是对于资源使用来说,互斥是必然的

  • 解决不可剥夺
    • 如果请求资源被拒绝,那么要释放自己所有的资源,在必要的时候在申请。
    • 如果请求的资源被占用,且当前线程优先级大于拥有该资源线程优先级,可以要求其释放资源。
  • 解决请求与保持
    • 可以一次性申请好所有资源,要么都没有,要么都有
    • 可以在请求前释放自己所有资源
  • 解决循环等待
    • 把资源按照一定排序标号,所有线程按照标号顺序获取资源

2、避免死锁

1、有序资源分配法:和解决循环等待类似,都是标号,按照标号顺序获取资源

2、设置加锁时限,超过时间放弃手中资源。

3、银行家算法:相当于系统(银行)给进程(企业家)分配资源(贷款)

假设10个资源

序号已有最大
a16
b15
c24
d47

现在空闲2个单位,有了这两个单位,可以拖延除了c以外其他人的请求,因此可以先完成c,释放4个资源,而这四个资源可以完成b,d,依次类推,如果一个人都无法满足,说明该状态不安全(不代表已经死锁),如果任意一个进程发出最大额度的请求都会造成死锁。因此银行家避免达到不安全状态即可。

3、死锁检测

  • 每种类型一个资源的死锁检测:每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中,最后检测是否成环。见现代操作系统第四版P252。
  • 每种类型多个资源的死锁检测:通过基于矩阵的算法检测。对可以运行的进程做标记,循环执行,最后没被标记的就是死锁的,无法被执行到的。

4、解除死锁

  • 资源剥夺法。挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。
  • 进程回退法。让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。
  • 撤销进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。