首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >死锁的常见原因是什么?

死锁的常见原因是什么?
EN

Stack Overflow用户
提问于 2009-02-09 14:20:46
回答 12查看 31.7K关注 0票数 40

死锁很难找到,而且很难消除。

如何在我的代码中找到死锁的错误来源?有没有什么“死锁模式”?

在我的特殊情况下,它处理数据库,但这个问题对于每个死锁都是开放的。

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2009-02-09 14:28:57

更新:这篇最近的MSDN文章Tools And Techniques to Identify Concurrency Issues可能也会引起人们的兴趣。

Stephen Toub在MSDN文章Deadlock monitor中指出了发生死锁的以下四个必要条件:

  • 特定资源的有限数量。对于C#中的监视器(使用lock关键字时使用的监视器),这个有限的数字是1,因为监视器是互斥锁(这意味着一次只能有一个线程拥有一个监视器)。
  • 持有一种资源并请求另一种资源的能力。在C#中,这类似于在释放第一个锁之前先锁定一个对象,然后再锁定另一个对象,例如:

代码语言:javascript
复制
lock(a)
{
...
    lock(b)
    {
            ...
    }
}

  • 没有抢占功能。在C#中,这意味着一个线程不能强制另一个线程释放锁。
  • 循环等待条件。这意味着有一个线程周期,每个线程都在等待下一个释放资源,然后才能继续。

他继续解释说,避免死锁的方法是避免(或阻止)条件4。

用于避免和检测死锁的

Joe Duffy discusses several techniques,其中包括一种称为锁平衡的方法。在锁级别中,锁被分配了数值,线程必须只获取数字比它们已经获取的锁更大的锁。这防止了循环的可能性。如今,在典型的软件应用程序中通常也很难做好,并且在每个锁获取上都不遵循锁级别会导致死锁。

票数 29
EN

Stack Overflow用户

发布于 2009-02-09 14:25:31

典型的死锁场景是A持有锁X并希望获取锁Y,而B持有锁Y并希望获取锁X。由于两者都不能完成它们试图做的事情,因此双方都将永远等待(除非使用超时)。

在这种情况下,如果A和B以相同的顺序获取锁,则可以避免死锁。

票数 15
EN

Stack Overflow用户

发布于 2009-02-09 14:35:53

确保所有事务以相同的顺序影响表是避免最常见的死锁的关键。

例如:

事务A

代码语言:javascript
复制
UPDATE Table A SET Foo = 'Bar'
UPDATE Table B SET Bar = 'Foo'

事务B

代码语言:javascript
复制
UPDATE Table B SET Bar = 'Foo'
UPDATE Table A SET Foo = 'Bar'

这极有可能导致死锁,因为事务A获得表A上的锁,事务B获得表B上的锁,因此在另一个命令完成之前,它们都不会获得第二个命令的锁。

所有其他形式的死锁通常是由于在分配资源时的高强度使用和SQL Server内部死锁引起的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/528303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档