[英]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.