c++ - 这个简单的(原子的)锁线程安全吗?

标签 c++ multithreading c++11 thread-safety

这段代码是线程安全的吗?我应该在函数 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 操作应该阻塞,直到获取成功。

关于 volatilethe docs std::atomic 的指定(关于 = 运算符):

Atomically assigns a value t to the atomic variable. Equivalent to store(desired).

然后关于store:

void store( T desired, memory_order = std::memory_order_seq_cst );

然后关于memory_order = std::memory_order_seq_cst:

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

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

Within a thread of execution, accesses (reads and writes) to all volatile objects are guaranteed to not be reordered relative to each other, but this order is not guaranteed to be observed by another thread, since volatile access does not establish inter-thread synchronization.

关于c++ - 这个简单的(原子的)锁线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12340208/

相关文章:

c++ - Memcpy 意外行为

c++ - MPI_Isend/Recv-是否存在死锁?

multithreading - 在 Kotlin Native 中,如何将对象保存在单独的线程中,并在不使用 C 指针的情况下从任何其他线程中改变其状态?

使用 100% 单 CPU 内核的 Java Web 应用程序

c++ - 用空花括号初始化

c++ - lambda 函数中的 max_element

c++ - 叮当格式 : disable ordering includes

c++ - 在循环c++中重用线程

c++ - 使用条件变量进行双向通信时出现死锁

c++ - 在模板中将 char 转换为 int 引用