这个简单的(原子)锁线程安全吗

Is this simple (atomic) lock thread safe?

本文关键字:线程 安全 原子 简单      更新时间:2023-10-16

这段代码是线程安全的吗?函数sig中应该有volatile吗?(例如:void Unlock() volatile {v=0;})如果不是,我该如何确保线程安全?

class SimpleLock {
    std::atomic<int> v;
public:
    bool try_lock() { int z=0; return v.compare_exchange_strong(z, 1); }
    void lock() { while(try_lock()==false) std::this_thread::yield(); }
    void unlock() {v=0;}
};

是的,它是线程安全的,尽管您可以将Lock重命名为TryLock,因为在成功之前,您不会在循环中调用CAS。传统上,Lock操作被认为是阻塞的,直到获取成功。

关于volatilestd::atomic的文档指定(关于=运算符):

以原子方式为原子变量指定一个值t。相当于存储(所需)。

关于store:

无效存储(T所需,memory_order=std::memory_order_seq_cst);

那么关于memory_order = std::memory_order_seq_cst:

  • 写入线程中的任何写入都不能在原子之后重新排序商店
  • 在原子加载之前,不能对读取器线程中的任何读取进行重新排序
  • 在标记为std::memory_order_seq_cst的所有原子操作之间建立同步。所有使用这种原子的线程操作查看相同的内存访问顺序

所以不,这里不需要volatile。此外,volatile的保证比上面的弱(事实上,volatile在C++中基本上是无用的):

在执行线程中,访问(读取和写入)所有易失性对象保证不会相对于每个对象重新排序其他,但不能保证其他人遵守此命令线程,因为volatile访问不会建立线程间同步。