死锁

     

 什么是死锁?死锁就是这样的情况,某个任务在等待另一个任务,而后者又在等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁。这就是一个任务间互相等待的连续循环,没有哪个线程能继续。死锁的可怕并不在于它马上发生,可怕的是任何加锁的程序够可能发生死锁的危险。防止死锁是设计并发编程一开始就必须考虑的事情。要防止死锁,就必须知道死锁的发生条件。
       会产生死锁必须满足一下四个条件:
       1.互斥条件。任务在使用的资源中至少有一个是不可能共享的;
       2.至少有一个任务它必须持有一个资源且正在等待获取一个当前被别的任务持有的资源;
       3.资源不能被任务抢占,任务必须把资源释放当做普通事件;
       4.必须有循环等待,这时一个任务等待其他任务所持有的资源,后者又在等待另一个任务所持有的资源,这样就会使得有一个任务在等待第一个任务所持有的资源。
       我们接下来就是分析这四个条件。对于条件1,当然会有一个疑问,任务就必须持有资源吗?为什么就不可以没有资源?既然说这四个条件必不可少,那么,我们就先假设可以没有持有资源,看看会不会发生死锁。进入下一个条件。条件2,至少有一个任务必须持有一个资源且正在等待获取一个当前被别的任务持有的资源,后面的没啥好讲的,因为正是这个行为使得死锁发生,但是前面呢?重点是“至少”后面跟着的是“任务”,   这点倒也没啥好讲的,因为就是有一个以上的任务才会发生死锁啊。请原谅我总是用“没啥好讲”这个词,但是有些问题还是很浅然的,而且并不是问题的疑惑点,所以我必须特意强调,以免大家的视线被拐跑了。还有一个重点,就是这个任务必须持有一个资源,这点我还是想说那个词,但是我忍住了,好吧,既然是循环,那么这个任务上的资源一定会被其他任务获取,所以该任务必须持有一个会被其他任务等待获取的资源。所以前面的假设不成立,任务必须持有资源,但是不可能共享的资源就一定必须持有吗?继续假设没有,看看怎样。进入下个条件。条件3中的情况是很重要的,因为就是每个任务都是那么礼貌,所以才会出现这样的循环,如果有谁能够打破这种和谐的局面,循环的死锁就会被打破,而所谓的把资源释放当做普通事件,就是说,它们认为,必须等待该资源被其他任务释放,它们才有资格去获取。哦,这帮绅士却给我们带来这么大的麻烦!我们又怎么能去指责它们呢?因为教导它们要做绅士的就是我们自己啊!所以说,现在做父母的真是难做啊,教孩子做个好人怕吃亏,做个坏人又不行,好人好太过头就变成死愚了。好了,问题扯远了,就接着我们的疑问下去吧。条件4,必须有循环等待,这就真的是得用那个词了,因为这就是死锁啊!所以,到了这里,我们可以发现一个问题,我的假设并没有出现任何问题啊,任务好像可以没有一个不可能共享的资源,这到底是怎么回事呢?让我们再来想想这个问题,不可能共享,那么其他任务就压根不会打它的主意,因为它不是抢夺的对象,那么对于死锁来说,它到底有什么意义?各位,有没有看到重点,就是那个“不可能”,不可能共享,它的具体意思到底是什么呢?不可能,就是说它绝对不会被共享,但并不代表它本来不是可共享,就像死锁,现在可共享也变成不可能共享,所以这个资源应该是原本可被其他任务共享,但是现在不可共享吗?既然说是条件,那么应该不会是这种从结果出发而导出的条件,所以,前面的论述应该是错的。后来我根据一些例子推敲一下,就可以明白,这个不可能共享的资源是指需要使用到共享资源的不共享资源,那么,问题就可以改一下,如果资源都是共享的,会是怎样?资源如果都是共享的,那么得到显然就不会发生这种等待获取锁的现象,因为任务所等待的锁是其中一个共享资源的锁,但是它的其他共享资源并没有被其他任务锁住,所以其他任务还是可以获取锁做些行动,那么,死锁就不会发生,至少,只是有点卡而已。
       讲完上面4个条件,那么,接下来自然就是如何使死锁不发生。这个很简单,就是破坏死锁中的任意一个条件就可以。那么,哪个最容易被破坏呢?第4个。破坏循环等待是比较容易的,因为设计循环就是我们,而其他条件有时可能真的是我们无法改变的。 
posted @ 2012-08-28 17:19  文酱  阅读(268)  评论(0编辑  收藏  举报