0

我担心嵌套指针和访问,特别是在处理基于无锁节点的树结构时是否有办法避免这个 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
4

1 回答 1

1

您的示例并没有真正显示 ABA 问题。维基百科:

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

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

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

于 2020-05-27T10:35:32.297 回答