Multithreading 绕线条件和死锁之间的区别

Multithreading 绕线条件和死锁之间的区别,multithreading,deadlock,race-condition,Multithreading,Deadlock,Race Condition,在编程术语中,死锁和绕行条件有什么区别?我想你指的是“绕行条件”而不是“绕行条件”(我听过这个术语…) 基本上,死锁是指线程a在等待资源X的同时持有资源Y上的锁,线程B在等待资源Y的同时持有资源X上的锁。线程阻塞,等待彼此释放锁 这个问题的解决方案是(通常)确保在所有线程中以相同的顺序锁定所有资源。例如,如果您总是在资源Y之前锁定资源X,那么我的示例永远不会导致死锁 竞态条件是指您依赖于以特定顺序发生的特定事件序列,但如果另一个线程同时运行,则可能会出现混乱。例如,要将新节点插入到链接列表中,需

在编程术语中,死锁和绕行条件有什么区别?

我想你指的是“绕行条件”而不是“绕行条件”(我听过这个术语…)

基本上,死锁是指线程a在等待资源X的同时持有资源Y上的锁,线程B在等待资源Y的同时持有资源X上的锁。线程阻塞,等待彼此释放锁

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

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

newNode->next = listHead;
listHead = newNode;
但如果两个线程同时执行此操作,则可能会出现如下情况:

Thread A                       Thread B
newNode1->next = listHead
                               newNode2->next = listHead
                               listHead = newNode2
listHead = newNode1
如果发生这种情况,那么线程B对列表的修改将丢失,因为线程A会覆盖它。根据具体情况,情况可能更糟,但这是最基本的

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

死锁是指两个(或更多)线程相互阻塞。通常这与试图获取共享资源的线程有关。例如,如果线程T1和T2需要获取资源A和B以完成其工作。如果T1获取资源A,那么T2获取资源B,那么T1可以在T2等待资源A的同时等待资源B。在这种情况下,两个线程将无限期地等待另一个线程持有的资源。这些线程被称为死锁


当两个线程以否定(错误)方式交互时,会发生争用情况,具体取决于它们不同指令的执行顺序。例如,如果一个线程设置了一个全局变量,然后第二个线程读取并修改该全局变量,而第一个线程读取该变量,则第一个线程可能会遇到错误,因为该变量发生了意外更改。

使用传统示例来考虑竞争条件。假设你和一个朋友在同一个银行账户上有一张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美元(你的交易永远失去了,但你仍然有钱)

这就是所谓的竞争条件。您希望事务是可串行化的,也就是说,无论您如何交错各个指令执行,最终结果都将与相同事务的某些串行计划完全相同(意味着您在没有交错的情况下一个接一个地运行它们)。解决方案是引入锁定;但是,不正确的锁定可能导致死锁

当共享资源发生冲突时,会发生死锁。这有点像第二十二条军规

   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
上的锁,但它正在等待T2持有的
y
的锁

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

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

这些都是微不足道的例子,我只是用了一些你可能已经看过的例子,如果你在这方面修过本科课程的话。事实上,解决死锁问题可能比这困难得多,因为您往往拥有不止一对资源和一对事务

希望这有点帮助。一如既往,使用维基百科作为CS概念的起点:

死锁:

  • 2个或多个线程彼此等待以无限时间释放资源时,就会发生这种情况
  • 在这种情况下,线程处于阻塞状态且不执行
  • 比赛/比赛条件:

  • 2个或多个线程并行运行时会发生这种情况,但如果所有操作都按顺序执行,则最终会给出错误且不相等的结果
  • 在这里,所有线程都运行并执行这些操作

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

    如果您需要,请使用编程语言