为什么c++ 11 CAS操作使用两个指针形参

Why do C++11 CAS operations take two pointer parameters?

本文关键字:两个 形参 指针 c++ CAS 操作 为什么      更新时间:2023-10-16

许多c++ 11 CAS操作(例如,atomic_compare_exchange_weak, atomic_compare_exchange_strong)接受两个指针和一个值,即:

bool atomic_compare_exchange(T* pointer, T* expected,       // pseudodeclaration!
                             T desired);

相比之下,来自Microsoft、gcc和Intel的CAS操作都使用一个指针和两个值:

long InterlockedCompareExchange(long* pointer, long desired,       // Microsoft
                                long expected);
int __sync_bool_compare_and_swap (T* pointer, T expected,          // gcc and
                                  T desired);                      // Intel

为什么c++ 11 CAS函数接受两个指针和一个值,而不是看起来更传统的一个指针和两个值?

c++ 11的方式更有用:如果交换失败,则*expected 更新为新的当前值。这使得在循环中使用该函数变得很容易:

T value = x.load();
T newvalue = frob(value);
while (!atomic_compare_exchange(&x, &value, newvalue))
{
    newvalue = frob(value);
}

使用Microsoft签名,测试操作是否成功更麻烦,对于GCC的__sync_type版本也是如此。使用GCC的__sync_bool,您甚至需要在每次交换失败时执行另一次加载。

我不明白为什么你不能两者兼得。在我的用例中,c++版本没有那么有用。我想等到一个变量有了值,然后我想把它设为一个新值。

带有GCC的参数:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { }
与c++ 11:

auto tmp = expected;
while (!value.compare_exchange_weak(tmp,desired)) 
{
  tmp = expected;
}