竞赛条件和死锁之间的区别

时间:2010-06-28 04:37:18

标签: multithreading deadlock race-condition

编程术语中死锁和竞争条件之间有什么区别?

5 个答案:

答案 0 :(得分:60)

使用传统示例考虑竞争条件。假设您和一位朋友拥有同一银行账户的ATM卡。现在假设该帐户中有100美元。考虑当你试图提取10美元并且你的朋友试图在同一时间提取50美元时会发生什么。

想想会发生什么。 ATM机必须接受您的输入,读取您帐户中当前的内容,然后修改金额。请注意,在编程术语中,赋值语句是一个多步骤过程。

因此,标记两个交易T1(您提取10美元)和T2(您的朋友提取50美元)。现在,左下方的数字表示时间步长。

       T1                        T2
       ----------------          ------------------------
 1.    Read Acct ($100)          
 2.                              Read Acct ($100)
 3.    Write New Amt ($90)
 4.                              Write New Amt ($50)
 5.                              End
 6.    End

在两个交易完成后,使用此时间线,如果您不使用任何类型的锁定机制,该帐户可以使用50美元。这比它应该多10美元(你的交易永远丢失,但你还有钱)。

这是一种叫做竞争条件。您想要的是事务是 serializable ,无论您如何交错各个指令执行,最终结果将与某些串行计划完全相同(意思是一个接一个地运行它们,没有交错)相同的事务。解决方案同样是引入锁定;但不正确的锁定会导致死锁。

当共享资源发生冲突时会发生死锁。它有点像Catch-22。

   T1            T2
   -------       --------
1.  Lock(x)
2.               Lock(y)
3.  Write x=1
4.               Write y=19
5.  Lock(y)
6.  Write y=x+1
7.               Lock(x)
8.               Write x=y+2
9.  Unlock(x)
10.              Unlock(x)
11. Unlock(y)
12.              Unlock(y)

您可以看到在时间7发生死锁,因为T2尝试获取x上的锁,但T1已经锁定x,但它正在等待{{1}的锁定,T2持有。

这很糟糕。您可以将此图转换为依赖图,您将看到有一个循环。这里的问题是x和y是可以一起修改的资源。

使用多个锁定对象(资源)防止此类死锁问题的一种方法是引入排序。您可以看到,在上一个示例中,T1已锁定y,然后x,但T2已锁定y,然后y。如果这两个事务都遵守某些排序规则,即“x始终在x之前锁定”,则不会出现此问题。 (您可以在考虑此规则的情况下更改上一个示例,并且不会发生死锁)。

这些是微不足道的例子,我真的只是使用了你可能已经看过的例子,如果你已经采取了任何类型的本科课程。实际上,解决死锁问题可能比这更难,因为您往往拥有多个资源和几个事务交互。

希望这会有所帮助。与往常一样,使用维基百科作为CS概念的起点:

http://en.wikipedia.org/wiki/Deadlock

http://en.wikipedia.org/wiki/Race_condition

答案 1 :(得分:12)

死锁是两个(或更多)线程相互阻塞的时候。通常这与尝试获取共享资源的线程有关。例如,如果线程T1和T2需要同时获取资源A和B以便完成其工作。如果T1获取资源A,则T2获取资源B,然后T1在等待资源A时等待资源B.在这种情况下,两个线程将无限期地等待另一个线程持有的资源。据说这些线程已陷入僵局。

当两个线程以负面(错误)方式交互时,会出现竞争条件,具体取决于执行不同指令的确切顺序。例如,如果一个线程设置了一个全局变量,那么第二个线程将读取并修改该全局变量,并且第一个线程读取该变量,第一个线程可能会遇到错误,因为该变量已意外更改。

答案 2 :(得分:5)

我认为你的意思是“竞争条件”而不是“围绕条件竞赛”(我听说过那个词......)

基本上,死锁是线程A在资源Y上持有锁定时等待资源X的情况,线程B在资源X上持有锁定时等待资源Y.线程阻塞彼此等待释放他们的锁。

此问题的解决方案(通常)是为了确保您锁定所有线程中相同顺序中的所有资源。例如,如果您始终在资源Y之前锁定资源X ,那么我的示例永远不会导致死锁。

竞争条件是指您依赖于按特定顺序发生的特定事件序列,但如果另一个线程同时运行,则可能会混乱。例如,要将新节点插入链接列表,您需要修改列表头,通常是这样的:

newNode->next = listHead;
listHead = newNode;

但如果两个线程同时执行此操作,那么您可能会遇到这样的情况:

Thread A                       Thread B
newNode1->next = listHead
                               newNode2->next = listHead
                               listHead = newNode2
listHead = newNode1

如果发生这种情况,那么线程B对列表的修改将会丢失,因为线程A会覆盖它。它可能更糟糕,取决于具体情况,但这是它的基础。

此问题的解决方案通常是确保您包含正确的锁定机制(例如,在您想要修改链接列表时随时取出锁定,以便一次只修改一个线程)。 / p>

答案 3 :(得分:4)

Deadlock :

  1. This happens when 2 or more threads are waiting on each other to release the resource for infinite amount of time.
  2. In this the threads are in blocked state and not executing.

Race/Race Condition:

  1. This happens when 2 or more threads run in parallel but end up giving a result which is wrong and not equivalent if all the operations are done in sequential order.
  2. Here all the threads run and execute there operations.

In Coding we need to avoid both race and deadlock condition.

答案 4 :(得分:0)

如果您没有锁定共享资源并且被多个线程访问,那么请尽量使用编程语言,然后将其称为“竞赛条件”;第二种情况,如果您锁定了资源并且未正确定义对共享资源的访问顺序,则线程可能等待资源使用很长时间,然后出现“僵局”