关于死锁

    科技2024-12-04  23

    文章目录

    什么是死锁死锁产生的原因:产生死锁的四个必要条件:处理死锁的方法预防死锁避免死锁检测死锁解除死锁

    基本网上收集以及《UNIX环境高级编程》上的内容。

    什么是死锁

    死锁是指两个或两个以上的进程(线程)在运行过程中因争夺资源而造成的一种僵局(Deadly-Embrace) ) ,若无外力作用,这些进程(线程)都将无法向前推进。

    ps:《UNIX环境高级编程》p322:

    线程试图对同一个互斥量加锁两次,它自身就会陷入死锁状态。

    死锁产生的原因:

    竞争不可抢占资源引起死锁,例如:系统中只有一台打印机,可供进程P1使用,假定P1已占用了打印机,若P2继续要求打印机打印将阻塞。竞争可消耗资源(临时资源)引起死锁,临时资源包括硬件中断、信号、消息、缓冲区内的消息等,通常消息通信顺序进行不当,则会产生死锁。进程推进顺序不当引起死锁:例如,进程A等待进程B发的消息,进程B又在等待进程A 发的消息

    产生死锁的四个必要条件:

    互斥条件: 进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。不可剥夺条件: 进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。请求与保持条件: 进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。循环等待条件: 若干进程间形成首尾相接循环等待资源的关系,发生死锁时,必然存在一个进程–资源的环形链。

    以上这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

    处理死锁的方法

    参考:死锁面试题(什么是死锁,产生死锁的原因及必要条件)_hd12370的博客-博客

    预防死锁

    通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个条件,来防止死锁的发生。

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

    1、以确定的顺序获得锁 如果必须获取多个锁,那么在设计的时候需要充分考虑不同线程之前获得锁的顺序。如果两个线程获得锁的时序图如下: 就会产生死锁,两个线程会陷入僵持状态。 如果此时把获得锁的时序改成: 那么死锁就不会发生。

    针对两个特定的锁,可以尝试按照锁对象的hashCode值大小的顺序,分别获得两个锁,这样锁总是会以特定的顺序获得锁,那么死锁也不会发生。问题变得更加复杂一些,如果此时有多个线程,都在竞争不同的锁,简单按照锁对象的hashCode进行排序(单纯按照hashCode顺序排序会出现“环路等待”),可能就无法满足要求了,这个时候开发者可以使用银行家算法,所有的锁都按照特定的顺序获取,同样可以防止死锁的发生,该算法在这里就不再赘述了,有兴趣的可以自行了解一下。

    2、超时放弃 当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。 还是按照之前的例子,时序图如下:

    避免死锁

    预防死锁是设法至少破坏产生死锁的四个必要条件之一,严格的防止死锁的出现。预防死锁的几种策略,会严重地损害系统性能(策略过于严格,因为即使满足四个必要条件,也不意味着死锁一定会发生)。

    因此在避免死锁时,要施加较弱的限制,从而获得较满意的系统性能。由于在避免死锁的策略中,允许进程动态地申请资源。因而,系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程;否则,进程等待。其中最具有代表性的避免死锁算法是银行家算法。

    银行家算法:首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程直到同意该请求后系统状态仍然是安全的。

    检测死锁

    允许系统在运行过程中发生死锁,但可设置检测机制及时检测死锁的发生,并采取适当措施加以清除(解除死锁)。

    1、首先为每个进程和每个资源指定一个唯一的号码; 2、然后建立资源分配表和进程等待表。

    解除死锁

    当检测出死锁后,便采取适当措施将进程从死锁状态中解脱出来。常采用的方法有:

    剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
    Processed: 0.016, SQL: 8