使用 test-and-set 原子操作实现互斥锁:它可以用于 2 个以上的线程吗?

Ign*_*ant 3 language-agnostic concurrency multithreading atomic test-and-set

我正在阅读有关测试和设置原子操作的维基百科文章。它说实现互斥的一种方法是使用基于测试和设置的锁。

但是,根据同一篇文章,test-and-set 操作具有有限的共识数,最多可以解决两个并发进程的无等待共识问题。

那么基于 test-and-set 操作的互斥锁是否只对两个线程有​​效?如果是这样,“实际”互斥是如何实现的?

Din*_*nei 5

需要注意的一件事是,互斥本质上等同于 2 个线程的共识。换句话说,实现互斥不需要n个线程的共识。-- @Eric的评论

我强烈推荐阅读Maurice Herlihy 和 Nir ​​Shavit 的The Art of Multiprocessor Programming。实际上,test-and-set 维基百科页面引用Herlihy的一篇文章说“test-and-set 有一个有限的共识数,最多可以解决两个并发进程的无等待共识问题”。

本书的第 5 章讨论了使用原始同步操作的共识,但我相信第 7 章会引起您的兴趣:它们讨论了如何使用 TAS(测试和设置)指令在 Java 中实现锁。来自第 145 页的剧透:

public class TASLock implements Lock {
  AtomicBoolean state = new AtomicBoolean(false);
  public void lock() {
    while (state.getAndSet(true)) {}
  }
  public void unlock() {
    state.set(false);
  }
}
Run Code Online (Sandbox Code Playgroud)

那么基于 test-and-set 操作的互斥锁是否只对两个线程有​​效?

简单的答案是:不,它们适用于两个以上的线程。

如果是这样,“实际”互斥是如何实现的?

同一个维基百科页面引用了 CAS(比较和交换)作为 TAS 的更强大的替代方案,但该书对这个问题进行了广泛的讨论。此外,这已经在 SO 中提出过,所以我建议阅读互斥锁如何实现的答案