假设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吗?我所看到的所有尝试都有竞争条件或不保证无锁属性。我不相信这是可能的。
答案 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,但它不会等待。