这个收购围栏是否被观察到?

Is this acquire fence observed?

这个问题是关于 C++ 中的独立栅栏

为了封装acquire和release fences的使用,我写了如下代码:

#include <thread>
#include <atomic>
#include <cassert>

class sync {
    std::atomic<bool> flag{false};

public:
    void release()
    {
        std::atomic_thread_fence(std::memory_order_release);
        flag.store(true, std::memory_order_relaxed);
    }

    bool acquire()
    {
        return flag.load(std::memory_order_relaxed);
        std::atomic_thread_fence(std::memory_order_acquire); // Is this acquire fence observed by the application ?
    }
};

int main()
{
    sync s;
    int data = 0;

    std::thread t1{[&] { data = 12; s.release(); }};
    std::thread t2{[&] { if (s.acquire()) assert(data==12); }};

    t1.join(); t2.join();
}

我认为围栏的位置正确('release' 在商店之前,'acquire' 在装载之后)。

我不确定 load/acquire 是否有效。
由于 acquire fence 是 after load/return 语句,我想知道它是否被考虑在内。

acquire fence 的这种用法是否正确?

您不能在 return 之后放置围栏。您放置的获取栅栏是无法访问的代码。 std::atomic_thread_fence 是一个函数。不要将其视为一种语言功能。如果您不调用该函数,则不会产生效果。

我在 MSVC 19.16 (VS 2017 15.9.13) 中使用编译器警告级别 4(/w4 标志)编译了您的示例。我收到 "unreachable code" 警告。

GCC "unreachable code" 警告已在 4.5 版中删除

修复(改编自https://preshing.com/20130922/acquire-and-release-fences/):

bool acquire()
{
    if (flag.load(std::memory_order_relaxed))
    {
        std::atomic_thread_fence(std::memory_order_acquire);
        return true;
    }
    return false;
}