死锁

什么是死锁

西门追雪和他女友去约会,女友说:“你必须给我买 XXX 我才会继续和你 OOO”,而西门追雪说:“你先 OOO 我才给你买 XXX”。

相信以上情景很多人都遇到过,都很无奈,是的,上边的便是我们常说的“死锁”,一旦出现,就很难解决。

在操作系统中,死锁的定义是:

两个线程之间互相等待彼此拥有的资源,进而导致两个线程都进入了漫无期限的等待中。

死锁是怎么产生的

在人类社会中,死锁之所以产生(你希望对方先交钱,但对方希望你先交货),完全是出于人类的欲念,所有人都希望优先得到更多的东西。

机器是没有情感的,那么,机器里头,又如何能产生死锁呢?

第一,互斥。机器得到了某资源,那么其它机器就不能拥有该资源,只能等待该机器释放(我的东西只属于我一个人)

第二,请求与保持。机器得到了某资源,没释放当前资源就去申请其它资源,如果其它资源被其它机器占用,该机器只能等待(机器的贪欲也是无穷无尽的)

第三,不剥夺。机器得到了某资源,其它机器不能抢夺(我的东西谁也不能抢)

第四,环路等待。A 等 B,B 等 C,C 又等 A,谁都不让步(真倔啊)

死锁避免

死锁是件麻烦的事,我们是“能避免就避免”,避免死锁,主要有银行家算法:在分配资源之前,先判断是否会进入不安全状态,如果不会进入不安全状态,就不分配资源。什么叫不安全状态呢?

分配资源时,如果我们没有足够资源同时分配给所有线程,但如果我们可以拖延其中绝大部分,只满足需求最少的那个,满足该线程后,线程执行完毕,释放出的资源又可以满足另一个线程,我们照旧,将释放出来的资源分给它,直到最后满足所有人,这样,就算是安全状态。

也就是说,如果我们连需求最少的那位都满足不了,就绝对是不安全状态,这种情况下,不能分配资源。

用银行家算法可以避免死锁,不过成本太高,缺乏实用价值。

死锁预防

既然死锁是不可避免的,而且死锁避免的成本极高,那么,我们能不能尽量预防死锁的产生呢?

预防死锁,只需要破坏死锁四个必要条件中的一个就可以了。

对于互斥独占,让进程尽可能少的申请资源,虽然独占,但独占得少,这一定程度可以缓解死锁频度,但不是好 IDEA。
对于不可抢夺,在发生死锁时就去强抢部分进程的资源。
对于占有与保持,在一个进程申请资源时,先全部释放所有持有的资源,再一次性地申请全部的资源。
对于环路,可以将资源按顺序标上号,规定进程申请资源时,必须按升序申请,不是升序的申请不予通过。