如何使用 c 11 CAS 实现 ABA 计数器?
要同时原子地更新两个值,请创建一个原子的相邻结构。假设您使用 std::atomic
注意原子对象应该是无锁的,特别是对于x86 CPU。像 gcc7 及更高版本的编译器可能会调用 libatomic 而不是使用内联锁 cmpxchg16b。在这种情况下,请考虑以下事项:
以下是展示这些特征的 C 11 代码示例:
#include <atomic> #include <stdint.h> using namespace std; struct node { struct alignas(2*sizeof(node*)) counted_ptr { node * ptr; uintptr_t count; // use pointer-sized integers to avoid padding }; // hack to allow reading just the pointer without lock-cmpxchg16b, // but still without any C++ data race struct counted_ptr_separate { atomic<node *> ptr; atomic<uintptr_t> count_separate; // var name emphasizes that accessing this way isn't atomic with ptr }; static_assert(sizeof(atomic<counted_ptr>) == sizeof(counted_ptr_separate), "atomic<counted_ptr> isn't the same size as the separate version; union type-punning will be bogus"); // TODO: write member functions to read next.ptr or read/write next_and_count union { // anonymous union: the members are directly part of struct node alignas(2*sizeof(node*)) atomic<counted_ptr> next_and_count; counted_ptr_separate next; }; };
总之,同时原子地修改两个值需要仔细的设计、编译器考虑和对齐优化。通过遵循这些准则,您可以使用高效且正确的代码在 C 11 中实现无锁 ABA 计数器。
以上是如何使用 CAS 在 C 11 中实现无锁 ABA 计数器并最小化性能开销?的详细内容。更多信息请关注PHP中文网其他相关文章!