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