可以使用CompareAndSwap实现CompareExchange吗?

时间:2010-03-17 16:22:13

标签: multithreading atomic

假设CompareAndSwap(或CAS)从未虚假失败,可以用CAS实现CompareExchange吗?

CompareExchange既获取指针,期望值又使用新值,并将指针引用的内存原子设置为新值(如果它与预期值匹配)。两者之间的区别在于CompareExchange返回内存区域的先前值,CompareAndSwap返回指示成功或失败的bool。

使用CompareExchange实现CAS非常简单:

int CompareExchange (int* p, int expected, int newvalue);

bool CAS (int* p, int expected, int newvalue)
{
   return CompareExchange (p, expected, newvalue) != expected;
}

...但是可以用CAS实现CompareExchange吗?我所看到的所有尝试都有竞争条件或不保证无锁属性。我不相信这是可能的。

2 个答案:

答案 0 :(得分:3)

我看不出它是怎么可能的。对于CAS失败的情况,您需要单独的操作来获取先前的值。这个单独的操作相对于CAS不是原子的。

你可以参与其中:

int CompareExchnage(int *p, int expected, int newvalue)
{
    if (CAS(p, expected, newvalue))
        return expected;
    else
        ???;
}

CAS出现问题的情况就是这样。让*p找到以前的值不会是相对于CAS的原子,因此您要么具有竞争条件,要么必须锁定CAS和*p取消引用。

答案 1 :(得分:2)

你可以,它是无锁的,但它不是等待的:

int CompareExchange(int *p, int expected, int newvalue)
{
    for (;;) {
        oldValue = *p;
        if (oldValue != expected)
            return oldValue;
        if (CAS(p, expected, newvalue))
            return expected;
    }
}

我们的想法是,从CompareExchange返回后修改* p与两个ifs之间的修改无法区分。

类似地,您可以基于CAS实现原子交换和原子获取和OP,但它不会等待。