ABA比赛条件

时间:2020-05-27 10:08:21

标签: c++ language-lawyer aba

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

我的关注如下:

Potential Problem

标准是否对此做出保证,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

1 个答案:

答案 0 :(得分:1)

您的示例并未真正显示出ABA问题。 Wikipedia:

[..]同步期间发生ABA问题,当两次读取一个位置,两次读取具有相同的值,并且“值相同”用于表示“没有任何变化”。但是,另一个线程可以在两次读取之间执行并更改值,执行其他工作,然后将值改回,因此,即使第二个线程的工作违反了该假设,也使第一个线程认为“什么都没有改变”。

也就是说,在指针被取消引用时,确保指针仍然有效(即,指向尚未释放的现有对象/内存)是您的责任。如果涉及多个线程,则您的职责是确保避免潜在的数据争夺所需的必要的先发生后关系(如果有)。

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