CompareExchange可以用CompareAndSwap来实现吗?
假设 CompareAndSwap(或 CAS)永远不会意外失败,CompareExchange 可以用 CAS 实现吗?
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 吗?我见过的所有尝试要么具有竞争条件,要么不保证无锁属性。我不相信这是可能的。
Assuming that CompareAndSwap (or CAS) never fails spuriously, can CompareExchange be implemented with 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. 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.
It's trivial to implement CAS with CompareExchange:
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? All the attempts I've seen either have race conditions or don't guarantee lockless properties. I don't believe it's possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不明白这怎么可能。对于 CAS 失败的情况,您需要单独的操作来获取之前的值。这个单独的操作相对于 CAS 来说不是原子的。
您可以部分解决:
在您遇到问题的情况下,CAS 会失败。使用
*p
查找前一个值相对于 CAS 而言不是原子的,因此您要么存在竞争条件,要么必须锁定 CAS 和*p
取消引用。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. This separate operation will not be atomic relative to the CAS.
You can get part way there:
It's the case where CAS fails where you have the problems. 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.可以,而且它是无锁的,但它不是无等待的:
其思想是,从 CompareExchange 返回后对 *p 的修改与两个 if 之间的修改没有区别。
同样,你可以基于CAS实现原子交换和原子取操作,但它不会是免等待的。
You can, and it is lock-free, but it is not wait-free:
The idea is that a modification of *p after returning from CompareExchange is indistinguishable from a modification between the two ifs.
Similarly, you can implement atomic exchange and atomic fetch-and-OP based on CAS, but it will not be wait-free.