这个锁的内存屏障是否正确?

chb*_*er0 5 c++ locking atomic spinlock

这样对吗?我假设在 上应用内存排序std::atomic_flag不为通用锁提供同步是否正确?

#include <atomic>

class Spinlock
{
public:
    Spinlock(): f(ATOMIC_FLAG_INIT) {}

    void lock()
    {
        while(f.test_and_set(std::memory_order_relaxed));
        std::atomic_thread_fence(std::memory_order_acquire);
    }
    void unlock()
    {
        std::atomic_thread_fence(std::memory_order_release);
        f.clear(std::memory_order_relaxed);
    }

private:
    std::atomic_flag f;
};
Run Code Online (Sandbox Code Playgroud)

如果这是一个愚蠢的问题,我很抱歉,但我觉得std::atmoic_thread_fence通用锁需要一个IS,并且memory_order_acquire在test_and_set和memory_order_release上应用clear是不够的,但我也不确定。

Nem*_*emo 1

通常的模式是使用test_and_set(memory_order_acquire)和clear(memory_order_release)。但我怀疑你已经知道了。

根据标准第29.8节[atomic.fences](2):

如果存在原子操作 X 和 Y,两者都对某个原子对象 M 进行操作,则释放栅栏 A 与获取栅栏 B 同步,使得 A 在 X 之前排序,X 修改 M,Y 在 B 之前排序,并且 Y 读取值如果是释放操作,则 X 写入的值或假设释放序列 X 中任何副作用写入的值都将成为头。

在你的代码中,A是你函数中的栅栏unlock();X 是clear(); Y 是你的函数中的栅栏lock();B 是test_and_set(). 因此,您的代码满足标准本部分的要求,因此您的代码unlock()和lock()函数可以正确同步。