什么是死锁?解决死锁有那几种策略?这些策略分别有哪些实现方法-查字典问答网
分类选择

来自李建军的问题

  什么是死锁?解决死锁有那几种策略?这些策略分别有哪些实现方法?

  什么是死锁?解决死锁有那几种策略?这些策略分别有哪些实现方法?

1回答
2020-09-05 16:29
我要回答
请先登录
陈胜勇

  在并发程序设计中,死锁(deadlock)是一种十分常见的逻辑错误.通过采用正确的编程方式,死锁的发生不难避免.

  死锁的四个必要条件

  在计算机专业的本科教材中,通常都会介绍死锁的四个必要条件.这四个条件缺一不可,或者说只要破坏了其中任何一个条件,死锁就不可能发生.我们来复习一下,这四个条件是:

  •互斥(Mutualexclusion):存在这样一种资源,它在某个时刻只能被分配给一个执行绪(也称为线程)使用;

  •持有(Holdandwait):当请求的资源已被占用从而导致执行绪阻塞时,资源占用者不但无需释放该资源,而且还可以继续请求更多资源;

  •不可剥夺(Nopreemption):执行绪获得到的互斥资源不可被强行剥夺,换句话说,只有资源占用者自己才能释放资源;

  •环形等待(Circularwait):若干执行绪以不同的次序获取互斥资源,从而形成环形等待的局面,想象在由多个执行绪组成的环形链中,每个执行绪都在等待下一个执行绪释放它持有的资源.

  解除死锁的必要条件

  不难看出,在死锁的四个必要条件中,第二、三和四项条件比较容易消除.通过引入事务机制,往往可以消除第二、三两项条件,方法是将所有上锁操作均作为事务对待,一旦开始上锁,即确保全部操作均可回退,同时通过锁管理器检测死锁,并剥夺资源(回退事务).这种做法有时会造成较大开销,而且也需要对上锁模式进行较多改动.

  消除第四项条件是比较容易且代价较低的办法.具体来说这种方法约定:上锁的顺序必须一致.具体来说,我们人为地给锁指定一种类似“水位”的方向性属性.无论已持有任何锁,该执行绪所有的上锁操作,必须按照一致的先后顺序从低到高(或从高到低)进行,且在一个系统中,只允许使用一种先后次序.

  请注意,放锁的顺序并不会导致死锁.也就是说,尽管按照锁A,锁B,放A,放B这样的顺序来进行锁操作看上去有些怪异,但是只要大家都按先A后B的顺序上锁,便不会导致死锁.

  举例

  假如有三个对象A、B、C,我们人为约定它们的锁序是:A先于B先于C.举例说来,下列锁序均为合法:

  •锁C,放C

  •锁B,放B

  •锁B,锁C,放B,放C

  •锁B,锁C,放C,放B

  •锁A,放A

  •锁A,锁C,放A,放C

  •锁A,锁C,放C,放A

  •锁A,锁B,放A,放B

  •锁A,锁B,放B,放A

  •锁A,锁B,锁C,放A,放B,放C

  •锁A,锁B,锁C,放C,放B,放A

  而在上面定义的系统中,可能导致发生死锁典型上锁序列包括:

  •锁B,锁A,锁C,放C,放A,放B

  (因为先B后A的上锁顺序违反了锁序约定,如果另一执行绪同时按照先A后B的顺序上锁,则可能由于执行绪甲获得了B,执行绪乙获得了A,而导致双方同时等待对方释放所持有的锁,从而形成死锁局面;解法是将操作序列中增加适当的锁操作,即改为锁B,放B,锁A,锁B,锁C,放C,放A,放B)

  或者说,只要拿锁的时候不出现逆序(例如拿着C的时候试图抓B或A,或者拿着B的时候试图抓A),并出现潜在逆序的时候先放掉“小”锁再抓大的,就一定不造成死锁了.

2020-09-05 16:33:05

最新问答

推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读

  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  •