linux:死锁形成原因以及四个必要条件,避免死锁的方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ChaseRaod/article/details/73161801

前面我们已经介绍过线程的基本概念,我们知道,同一个进程中的多个线程共用一份公共资源,这样就有可能造成互相争夺资源互相等待对方让步的问题,若双方都不肯让步,就会一直等待,这就是死锁

死锁形成的原因:
(1)系统资源不足,不能满足进程的资源要求,会导致多个线程争夺同一份资源
(2)进程(线程)推进的顺序不恰当
(3)资源分配不当

死锁出现的场景:
(1)多个线程:彼此申请对方资源而导致的死锁。A申请B的资源时,因为资源被占用,A会被挂起等待B释放资源,同时B申请A的资源,因资源被占用B挂起等待A释放资源,而AB都处于挂起状态又无法释放资源,便形成了死锁

(2)单个线程:A有自己的资源,但还要申请新的资源,而新的资源被占用,则A会挂起等待,同时会保护的资源而不释放,形成死锁。

死锁产生的必要条件:
(1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其他进程请求资源,则请求者只能等待,直至占有资源的进程用完释放。

(2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程阻塞,但又对自己已获得的资源保持不放。

(3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完由自己释放。

(4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2…Pn}中的P0正在等待一个P1占用的资源,P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

如何避免死锁?
(1)预防死锁
这是一种比较简单和直观的实现预防的方法。通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或多个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。

2) 避免死锁。

  在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。
  一般来说互斥条件是无法破坏的,所以在解除或者预防死锁时主要从其他三个方面入手
(1)破坏请求和保持条件

第一种协议:在所有进程开始运行之前,必须一次性的申请其在整个运行过程中的所有资源,这样便破坏了请求条件;只要一个进程中有一个资源不满足,必须释放他所占有的资源,这样便破坏了保持条件;

第二种协议:第二种协议是第一种协议的改进,它允许进程只要获得运行初期所需的资源后,便开始运行,在运行过程中在逐步释放已分配给自己的(破坏了保持条件),且已经用完的全部资源,然后再开始申请新的资源。

两种协议比较:第二种协议优于第一种协议,因为第一种协议会造成资源的严重浪费,使资源利用率大大的降低,也会由于占据大量资源导致其它进程的饥饿问题

(2)破坏不可抢占条件

方式一:当一个进程已经占有了某些不可抢占的资源时,又去申请新的资源而得不到满足时,就必须释放自己已经保持的所有资源(类似于上面的第一种协议中破坏保持条件),待以后需要的时候再重新申请;

方式二:如果系统中的进程的优先级不同时,当优先级高的进程去申请优先级低的进程所占据的资源时,操作系统就可以抢占优先级低的进程的资源;

(3)破坏循环等待条件

对系统所有资源进行线性排序并赋予不同的序号,这样我们便可以规定进程在申请资源时必须按照序号递增的顺序进行资源的申请,当以后要申请时需检查要申请的资源的编号大于当前编号时,才能进行申请。

3)检测死锁。

 通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源,然后采取适当措施,从系统中将已发生的死锁清除掉。

4)解除死锁。

  这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。

常见的避免死锁的算法
鸵鸟算法:
忽略该问题。
该算法可以应用在极少发生死锁的的情况下。为什么叫鸵鸟算法呢,因为传说中鸵鸟看到危险就把头埋在地底下,可能鸵鸟觉得看不到危险也就没危险了吧。跟掩耳盗铃有点像。(一般不用)

银行家算法:
指在分配资源之前先看清楚,资源分配后是否会导致系统死锁,如果会死锁,则不分配,否则就分配。

按照银行家算法的思想,当进程请求资源时,系统将按如下原则分配系统资源:

(1) 当一个进程对资源的最大需求量不超过系统中的资源数时可以接纳该进程。

(2) 进程可以分期请求资源,当请求的总数不能超过最大需求量。

(3) 当系统现有的资源不能满足进程尚需资源数时,对进程的请求可以推迟分配,但总能使进程在有限的时间里得到资源。

(4) 当系统现有的资源能满足进程尚需资源数时,必须测试系统现存的资源能否满足该进程尚需的最大资源数,若能满足则按当前的申请量分配资源,否则也要推迟分配。

没有更多推荐了,返回首页