比较和交换有什么用

本文关键字:什么 交换 比较 | 更新日期: 2023-09-27 18:32:00

我最近读到了比较和交换原子作用(CMPXCHG,.NET的Interlocked.CompareExchange,随便什么)。

我了解它在内部的工作方式,以及客户端如何使用它。

我不太清楚的是什么时候有人会使用 CAS?

维基百科 说:

CAS 用于实现同步原语,例如信号量和互斥体,同样更复杂的无锁和免等待算法。

那么,谁能给我一个更通用的真实用例,其中包含 CAS 用法的代码和描述?

这个问题与语言无关,所以任何语言都可以(首选基于 C 或 x86 汇编)。

谢谢!

比较和交换有什么用

这很容易通过示例看到。假设我们想在共享变量上原子并发地设置一个位:

int shared = 0;
void Set(int index) {
 while (true) {
  if (Interlocked.CompareExchange<int>(ref shared, shared | (1 << index), shared) == shared)
   break; //success
 }
}

如果我们看到"旧值"(即返回值)在此期间发生了变化,则检测失败。

如果没有发生这种情况,我们没有并发修改,所以我们自己的修改成功了。

你可以用这种技术实现非常复杂的东西。但是,越复杂,旋转造成的性能损失就越大。

我想强调的是,CAS 的一个关键特性是它可以失败,并且可以可靠地检测到故障。

您可以使用 CAS 在一个线程或进程中以原子方式设置值(位或字),同时测试另一个线程/进程是否尚未这样做。因此,它用于在多线程环境中获取标志或计数器。

附录 (2023 年 2 月)

例如,多个线程可以各自使用 CAS 指令将其进程 ID 交换为共享内存字(开始时保持零值)。然后,将其进程 ID 存储到单词中的第一个线程可以拥有共享单词正在保护的任何资源的所有权。

当进程使用资源完成后,它会将零存储到单词中,释放资源的所有权并允许其他线程轮到他们获取资源。

那么,谁能给我一个更通用的真实用例,其中包含 CAS 用法的代码和描述?

本文使用 CAS 实现没有锁的线程安全队列。

它有一些伪代码示例。