ABA 比赛条件

ABA Race Condition

我担心嵌套指针和访问,特别是在处理基于无锁节点的树结构时是否有办法避免这个 ABA 问题。

我担心的是:

标准是否对此做出保证,funcB 是否等同于 funcA?

如果这里有一个ABA问题,是否有针对无锁编程的嵌套成员访问的解决方案?

#include <atomic>
#include <iostream>

struct Foo
{
    std::atomic_int value;
};

struct Bar
{
    Foo * foo;
};

void funcB(Bar * bar)
{
    if (not bar->foo->value.fetch_or(1) )
    {
        //Something
    }
}

void funcA(std::atomic_int * bar)
{
    if (not bar->fetch_or(0))
    {
        //Something
    }
}

上面的汇编输出是:

funcB(Bar*):                          # @funcB(Bar*)
        mov     rax, qword ptr [rdi]
        lock            or      dword ptr [rax], 1
        ret
funcA(Foo*):                          # @funcA(Foo*)
        lock            or      dword ptr [rdi], 1
        ret

您的示例并没有真正显示 ABA 问题。 Wikipedia:

[..] the ABA problem occurs during synchronization, when a location is read twice, has the same value for both reads, and "value is the same" is used to indicate "nothing has changed". However, another thread can execute between the two reads and change the value, do other work, then change the value back, thus fooling the first thread into thinking "nothing has changed" even though the second thread did work that violates that assumption.

也就是说,有责任确保指针在它被取消引用的时间。如果涉及多个线程, 也有责任确保避免潜在数据竞争所必需的发生前关系(如果有的话)。

在无锁算法中避免 ABA 问题可能非常棘手。将此委托给已建立的内存回收方案通常是最简单的。我的 xenium 库提供了可用于此目的的各种回收方案的实现。