使用Load-link / store-conditional的无锁C ++ 11示例来防止ABA?

时间:2014-05-30 13:08:33

标签: c++ multithreading c++11 concurrency compare-and-swap

使用比较和交换(CAS)技术编写无锁代码时,会出现一个称为ABA问题的问题:

http://en.wikipedia.org/wiki/ABA_problem

通过比较价值" A"是有问题的,因为在两次观察之间仍然可能发生了写入。我继续阅读并找到了这个解决方案:

http://en.wikipedia.org/wiki/LL/SC

  

在计算机科学中,加载链接和存储条件(LL / SC)是一种   用于多线程实现的一对指令   同步。 Load-link返回内存的当前值   位置,而后续存储 - 条件相同的内存   仅当没有发生更新时,location才会存储新值   自加载链接以来的位置。这实现了一个   无锁原子读 - 修改 - 写操作。

如何修改典型的C ++无锁CAS技术以使用上述解决方案?有人能够展示一个小例子吗?

我不介意它的C ++ 11 / x86,x86-64特定于Linux(最好没有Win32答案)。

1 个答案:

答案 0 :(得分:4)

LL / SC是由某些体系结构(例如SPARC)实现的指令,以形成更高级别原子操作的基础。在x86中,您可以使用LOCK前缀来实现类似的目标。

要避免使用LOCK的x86上的ABA问题,您必须提供自己的保护以防止干预商店。一种方法是在相关内存旁边存储一个世代号(只是一个递增的整数)。每个更新器进行足够大的原子比较/交换,以包含数据和序列号。只有在找到正确的数据和正确的数字时,更新才会成功。同时,它会更新数字,以便其他线程看到更改。

你会注意到x86总是(?)提供了一个CMPXCHG指令,它的宽度是机器字的两倍(参见CMPXCHG8B和后来的CMPXCGH16B),可以使用为了这个目的。