简体   繁体   English

可以使用CompareAndSwap实现CompareExchange吗?

[英]Can CompareExchange be implemented with CompareAndSwap?

Assuming that CompareAndSwap (or CAS) never fails spuriously, can CompareExchange be implemented with CAS? 假设CompareAndSwap(或CAS)永远不会虚假失败,CompareExchange是否可以用CAS实现?

CompareExchange both take a pointer, an expected value, and a new value and atomically set the memory referenced by the pointer to the new value if it matches the expected value. CompareExchange都使用一个指针,一个期望值和一个新值,并在该指针引用的内存与期望值匹配的情况下自动将其设置为新值。 The difference between the two is that CompareExchange returns the previous value of the memory area and CompareAndSwap returns a bool indicating success or failure. 两者之间的区别在于,CompareExchange返回内存区域的先前值,而CompareAndSwap返回指示成功或失败的布尔值。

It's trivial to implement CAS with CompareExchange: 用CompareExchange实现CAS很简单:

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

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

... but is it possible to implement CompareExchange with CAS? ...但是可以用CAS实现CompareExchange吗? All the attempts I've seen either have race conditions or don't guarantee lockless properties. 我见过的所有尝试都有竞争条件,或者不能保证无锁属性。 I don't believe it's possible. 我不认为有可能。

I don't see how it's possible. 我不知道怎么可能。 For the case where CAS fails, you'll need a separate operation to get the previous value. 对于CAS失败的情况,您将需要单独的操作来获取先前的值。 This separate operation will not be atomic relative to the CAS. 相对于CAS,此单独操作将不是原子的。

You can get part way there: 您可以在那儿找到路:

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

It's the case where CAS fails where you have the problems. 在出现问题的情况下,CAS会失败。 Getting *p to find what the previous value is will not be atomic relative to CAS so you either have a race condition or you would have to lock around the CAS and the *p dereference. 获得*p来查找先前的值相对于CAS而言不是原子的,因此您可能会遇到竞争状况,或者必须锁定CAS和*p取消引用。

You can, and it is lock-free, but it is not wait-free: 您可以,它是无锁的,但它不是免费的:

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

The idea is that a modification of *p after returning from CompareExchange is indistinguishable from a modification between the two ifs. 这个想法是,从CompareExchange返回之后对* p的修改与两个if之间的修改是无法区分的。

Similarly, you can implement atomic exchange and atomic fetch-and-OP based on CAS, but it will not be wait-free. 同样,您可以基于CAS来实现原子交换和原子获取和操作,但它并非没有等待。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM