死锁的概念、产生的必要条件、避免和解决死锁的办法

什么是死锁?

死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 如下图所示:如果此时有一个线程 A,已经持有了锁 A,但是试图获取锁 B,线程 B 持有锁 B,而试图获取锁 A,这种情况下就会产生死锁。
死锁的概念、产生的必要条件、避免和解决死锁的办法

产生死锁的原因?

由于系统中存在一些不可剥夺资源,而当两个或两个以上进程占有自身资源,并请求对方资源时,会导致每个进程都无法向前推进,这就是死锁。
竞争资源

例如:系统中只有一台打印机,可供进程 A 使用,假定 A 已占用了打印机,若 B 继续要求打印机打印将被阻塞。
系统中的资源可以分为两类:

  1. 可剥夺资源:是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺,CPU 和主存均属于可剥夺性资源;
  2. 不可剥夺资源,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。

进程推进顺序不当
例如:进程 A 和 进程 B 互相等待对方的数据。

死锁产生的必要条件?

  1. 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
  2. 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
  4. 环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。

解决死锁的基本方法?

  1. 预防死锁
  2. 避免死锁
  3. 检测死锁
  4. 解除死锁

怎么预防死锁?

  1. 破坏请求条件:一次性分配所有资源,这样就不会再有请求了;
  2. 破坏请保持条件:只要有一个资源得不到分配,也不给这个进程分配其他的资源:
  3. 破坏不可剥夺条件:当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源;
  4. 破坏环路等待条件:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反。

怎么避免死锁?

银行家算法
当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源。若没超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若满足则按当前的申请量分配资源,否则也要推迟分配。

安全序列
是指系统能按某种进程推进顺序(P1, P2, P3, …, Pn),为每个进程 Pi 分配其所需要的资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺序地完成。这种推进顺序就叫安全序列【银行家算法的核心就是找到一个安全序列】。

系统安全状态
如果系统能找到一个安全序列,就称系统处于安全状态,否则,就称系统处于不安全状态。

怎么解除死锁?

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