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

ckv*_*ckv 47 multithreading deadlock race-condition

在编程术语中,死锁和围绕条件的竞争有什么区别?

Bob*_*toe 67

使用传统示例考虑竞争条件.假设您和一位朋友拥有同一银行账户的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
Run Code Online (Sandbox Code Playgroud)

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

这是一种所谓的竞争条件.你想要的是事务是可序列化的,无论你如何交织各个指令执行,最终结果将与一些串行调度完全相同(意味着你一个接一个地运行它们,没有交错)相同的交易.解决方案同样是引入锁定; 但不正确的锁定会导致死锁.

当共享资源发生冲突时发生死锁.它有点像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)
Run Code Online (Sandbox Code Playgroud)

您可以看到在时间7发生死锁,因为T2尝试获取锁定,x但T1已经保持锁定x但是它正在等待锁定y,T2保持.

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

防止多种锁定对象(资源)出现这种死锁问题的一种方法是引入排序.你看,前面的例子中,T1锁定x,然后y,但T2锁定y,然后x.如果这两个事务都遵守一些说明" x应始终锁定y"的排序规则,则不会发生此问题.(您可以在考虑此规则的情况下更改上一个示例,并且不会发生死锁).

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

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

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

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

  • 我相信死锁发生在第5行本身,因为y已被T2锁定. (6认同)

小智 14

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

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


cry*_*kid 6

死锁:

  1. 2个或更多线程彼此等待释放资源无限时间时,会发生这种情况。
  2. 在这种情况下,线程处于阻塞状态并且无法执行。

种族/种族条件:

  1. 两个或多个线程并行运行但最终给出的结果是错误的,并且如果所有操作都是按顺序进行的,则结果不相等。
  2. 在这里,所有线程都运行并在那里执行操作。

在编码中,我们需要避免竞争和死锁情况。


Dea*_*ing 5

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

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

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

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

newNode->next = listHead;
listHead = newNode;
Run Code Online (Sandbox Code Playgroud)

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

Thread A                       Thread B
newNode1->next = listHead
                               newNode2->next = listHead
                               listHead = newNode2
listHead = newNode1
Run Code Online (Sandbox Code Playgroud)

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

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