locking - 来自 "The Art of Multiprocessor Programming"的 LockTwo

标签 locking mutex

这是“多处理器编程的艺术”中两个线程的互文本实现

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() {}

他们指出,如果“一个线程先于另一个线程运行”,则此代码会死锁。任何人都可以描述没有发生死锁时交错执行的示例。

最佳答案

我的理解可能有缺陷,在这种情况下,有人希望能够澄清(cc @SonarJetLens)。

在一个线程完全领先于另一个线程的情况下,例如,线程 A 获取锁并等待,因为它是受害者。它无限期地等待直到线程 B 出现并将自己设置为受害者,从而让 A 进入其临界区。在这种情况下,我没有看到任何死锁发生:根据定义,死锁是指任何线程没有取得任何进展。

但是,请考虑线程 A 从不尝试重新获取锁的情况。在这种情况下,线程 B 将无限期地等待,永远无法到达它的临界区。对我来说,这看起来更像是饥饿,这意味着线程 B 被饿死并且永远无法获取线程。

如果程序在那里结束,那么线程 A 通过执行它的临界区已经取得了一些“进展”,而线程 B 没有,因此没有死锁。但是,存在饥饿,因为线程 B 试图获取锁但从未成功,因此与饥饿自由的定义相矛盾。

我希望这是有道理的,我没有在这里犯任何术语或定义错误,我真的希望有人澄清:)。

关于locking - 来自 "The Art of Multiprocessor Programming"的 LockTwo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17133394/

相关文章:

c++ - 如何实现多线程访问的类锁对象

c - pthreads互斥与信号量

go - 检测同一个 goroutine 连续两次调用 sync.Mutex.Lock()

mysql - 数据库多表更新同时永久访问

windows - 如何在 Windows 上以独占方式锁定文件?

c++ - 包含指针的原子结构

locking - 在 Unix 上正确处理 PID 文件的引用

ruby-on-rails - 如何让 redis-semaphore 队列 "task_3"直到 "task_1"和 "task_2"已解锁(rails)?

linux-kernel - 关于 linux 内核中的信号量 up() 和 mutex_unlock()

c++ - std::mutex 和 std::shared_mutex 的区别