atomic_compare_exchange用大于而不是等于?

时间:2013-07-17 13:41:53

标签: c++ c++11 atomic compare-and-swap

C ++ 11对atomic variables进行了“比较和交换”操作。

语义是:

  

以原子方式将obj指向的值与expected指向的值进行比较,如果相等,则将前者替换为desired(执行读 - 修改 - 写操作)。否则,将obj指向的实际值加载到*expected(执行加载操作)。

我想做同样的事情,但是当值相等时我不想设置*obj,而是希望当一个大于另一个时设置它(假设我们'重新谈论有序的类型。)

这是以某种方式支持的吗?也许可以通过一些黑客实现?

注意: CAS循环不适用于我,因为我正在比较的两个值可能会在非原子操作之间发生变化。

3 个答案:

答案 0 :(得分:7)

我认为你误解了比较和交换/交换是如何工作的:基本的想法是,看了当前值,你可以计算出一些相应的新值 - 然后你尝试更新。如果它成功 - 很好 - 继续你需要的任何东西,但如果它失败然后重新开始:查看其他线程放在那里的新值并考虑你现在需要的价值。

  

我希望在一个大于另一个时设置它(假设我们正在谈论一个有序类型)。

所以说你想要存储11但是只有当现有值仍然小于11时才会存储。你不会直接找到这样做的指令,但你可以用现有的比较和交换轻松完成:

int target_value = 11;
do {
    int snapped_x = x;
    if (snapped_x >= target_value)
        what do you want to do instead?
} while (!compare_and_swap(x, snapped_x, target_value));
         // ...or whatever your exact calling convention is...

你仍然可以得到你想要的行为,只是潜在的更高的失败/旋转率....

答案 1 :(得分:5)

根据要求,这是我的评论作为答案:


我也希望这存在,但据我所知(当然不适用于x86 / x64),除了概念上,当然还有(可能)使用多个原子指令的变通方法(哪些工作但不等待)。

答案 2 :(得分:-1)

这可能是一个古老的问题,但是我认为许多人会想要这种功能。 我想出了一个主意,在这里显示伪代码(我是linux内核的人,所以要使用一些内核函数)。

update(new)
{
  old = atomic_read(&pvalue);
  while (old < new) {
    v = atomic_cmpxchg(&pvalue, old, new);
    if (v != old) {
      old = v;
      continue;
    }
  }
}

对于旧值小于新值的代码,不会尝试使用cmpxchg。
如果有并发问题,请告诉我。谢谢:)