以下是“多处理器编程的艺术”
中两个线程的静默实现private int victim;
// thread-local index, 0 or 1
public void lock() {
int i = ThreadID.get();
victim = i; // let the other go first
while (victim == i) {} // spin
}
public void unlock() {}
他们说如果“一个线程先于另一个线程运行”,则此代码会死锁。任何人都可以在没有发生死锁的情况下描述交错执行的示例。
答案 0 :(得分:1)
我的理解可能有缺陷,在这种情况下,有人可以澄清(cc @SonarJetLens)。
在一个线程完全超前于另一个线程的情况下,我们有,例如,线程A获取锁并等待,因为它是受害者。它会无限期地等待,直到线程B出现并将自己设置为受害者,从而让A进入其关键部分。在这种情况下,我没有看到任何死锁发生:根据定义,死锁是指任何线程没有进展。
但是,请考虑线程A从不尝试重新获取锁的情况。在这种情况下,线程B将无限期地等待,永远无法到达它的关键部分。对我来说,这看起来更像是 starvation ,这意味着线程B被饿死了,永远无法获得线程。
如果程序在那里结束,那么线程A通过执行它的关键部分已经取得了一些“进展”,并且线程B没有,因此没有死锁。然而,由于线程B试图获得锁定而从未成功,因此存在饥饿,因此与饥饿自由的定义相矛盾。
我希望这是有道理的,我不会在这里做任何术语或定义错误,我真的希望有人澄清:)。
答案 1 :(得分:0)
基本上线程将在while循环中等待,直到另一个线程进入lock()并更改受害者字段的值。
如果一个线程完全在另一个线程之前运行,即
thread A writes victim = A ->
thread A reads Victim != A ->
thread A do Critical Section ->
thread B writes victim = B ->
thread B reads Victim != B ->
thread B do Critical Section
这将导致死锁,因为事件thread B writes victim = B
必须在thread A reads Victim != A
之前,否则事件线程A读取Victim != A
将无限期阻塞。
交错操作可以防止死锁,因为,例如,当线程B写入victim = B
,允许A完成并返回其关键部分时,线程B现在在while循环中等待victim != B
。当线程A重新进入锁定并更改受害者或另一个线程C进入锁定并更改受害者时,线程B将从while循环返回,从而允许B前进到其临界区。等
答案 2 :(得分:0)
想象一下以下场景:
线程A进入其周期并且受害者= i - > while(victim == true) - >中断
然后
线程B进入其周期并且受害者= i - > while(victim == true) - >中断
然后
线程A进入其周期并且受害者= i - > while(victim == true) - >中断
...
你可以看到这是如何永远持续的。
答案 3 :(得分:0)
我也会尝试回答这个问题,尽管我是这个部门的新手。
考虑以下情况(A& B是线程):
writeA(victim=A) -> readA(victim != A) -> CSA
类似地
writeB(victim=B) -> readB(victim != B) -> CSB
现在考虑以下情况:
Case 1:
当一个线程完全在另一个线程之前运行时,即A -> B
当thread A
首先启动时,它会设置victim=A
并等待,同时thread B
无法启动,因为它正在等待线程A完成其临界区的执行。因此,thread A
正在等待thread B
更改victim
,但B
正在等待thread A
完成其CSA
。因此,当两个线程在两个不同的条件下等待时,将发生死锁:
Thread A is waiting so that thread B sets victim=B whereas thread B is waiting so that thread A completes its critical section (CSA).
Case 2:
当线程交错执行时。
在这种情况下,因为两个线程几乎在同一时间开始(假设它们一次又一次地运行,可能是在循环中),它们将交替设置受害者,从而允许彼此交替运行。
答案 4 :(得分:0)
今天再次阅读后,我认为我的主意是“ LockTwo类不足,因为如果一个线程在另一线程之前运行completely
则会死锁。”
如果线程A和B被序列化,这意味着线程B等待线程A完成,那么线程A将永远不会通过“ LockTwo”获得锁,这在定义上是死锁:Freedom from Deadlock: If some thread attempts to acquire the lock, then some thread will succeed in acquiring the lock.
。
如果作者写出“ LockTwo类不足,因为只有一个线程会死锁。(虽然不需要锁)