死锁发生的条件 以及 如何避免

什么是死锁

当两个或者两个以上的进程,因为争夺资源而造成相互等待的状态,由于存在一种环路的依赖关系而永远的等待下去。

经典描述:“哲学家进餐问题”:

在这里插入图片描述
死锁:每个人都立即抓住自己左边的筷子,然后等待自己右边的筷子空出来,但同时又不放下已经拿到的筷子,形成一种相互等待的状态。饥饿:哲学家们都同时想吃饭,同时拿起左手边筷子,但是发现右边没有筷子,于是哲学家又同时放下左手边筷子,然后大家发现又有筷子了,又同时开始拿起左手边筷子,又同时放下,然后反复进行。

死锁的4个必要条件

  1. 互斥条件

指在一段时间内某资源只由一个进程占用。如果此时还有其他进程请求资源,则请求者只能等待,直至占有资源的进程完全释放。

  1. 请求和保持条件

指进程已经保持至少一个资源,又提出新的请求,而该资源已经被其他进程占有,此时请求已经阻塞,但又不释放自己的资源。

  1. 不剥夺条件

指进程已获得的资源,在未使用完之前不能被剥夺,只能等使用完后自己释放。

  1. 环路等待条件

在发生死锁时,必然存在一个进程–资源的环形链。

死锁的避免

1. 预防死锁

  • 破坏互斥条件

使用资源同时访问而非互斥使用,就没有进程会阻塞在资源上,从而不发生死锁。

  • 破坏请求和保持条件

采用静态分配的方式。意思是在进程执行之前就申请需要的全部资源,直至所有的资源全部获得后才开始执行,如果有一个资源不能获得,则也不给该进程分配其他的资源。

  • 破坏不剥夺条件

指当某进程获得了部分资源,但得不到其他资源,就释放已获得的资源,但是只适用于内存和处理器资源。

  • 破坏环路等待条件

给系统的所有资源编号,规定进程所请求的资源顺序必须按照资源的编号依次进行。

2. 设置加锁顺序

两个线程以不同的顺序获取相同的锁,就会发生死锁。
在这里插入图片描述
解决:按照相同的顺序来请求锁

在这里插入图片描述

3. 支持定时的锁(超时放弃)

有一项技术可以检测死锁和从死锁中恢复过来,就是LOCK类中的定时功能,代替内置锁机制。

当使用内置锁的时候,只要没有获得锁,就会永远等待下去,而trylock可以指定一个超时时间(Timeout),在等待超过时间后,就会返回一个错误信息,如果超时时限比获取锁的时间长很多,那么就可以在发生某个意外后重新获得控制权。
在这里插入图片描述

4. 死锁避免的算法

银行家算法

在这里插入图片描述
上图有五个进程,四个资源。左边的图表示进程已拥有的资源,右图表示还需要分配的资源。E表示总资源;P表示已分配资源、A表示可用资源。是向量而不是具体值。

检查一个状态是否安全算法如下:

  • 查找右图中是否有一行小于等于A向量,如果不存在表示该系统会发生死锁,状态不安全。
  • 如果存在,将该进程标记为终止,并把其已拥有的资源加到向量A。
  • 重复以上步骤,直到所有进程标记为终止,则状态安全。
  • 如果一个状态不安全,需要拒绝进入这个状态。

5. 死锁恢复

  • 资源剥夺

剥夺处于死锁的资源,但并不撤销此进程,直至死锁结束。

  • 进程回退

根据系统保存的检查点让所有的进程回退,直到足以解除死锁,这种措施要求系统建立保存检查点、回退及重启机制

  • 进程撤销

1、撤销陷入死锁的所有进程,解除死锁,继续运行。

2、逐个撤销陷入死锁的进程,回收其资源并重新分配,直至死锁解除。

可选择符合下面条件之一的先撤销:

1.CPU消耗时间最少者
2.产生的输出量最小者
3.预计剩余执行时间最长者
4.分得的资源数量最少者后优先级最低者

  • 系统重启

结束所有进程的执行并重新启动操作系统。这种方法很简单,但先前的工作全部作废。

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页