这个简单的(原子)锁定线程是否安全?

时间:2012-09-09 15:06:50

标签: 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;}
};

1 个答案:

答案 0 :(得分:8)

是的,虽然您可以将Lock重命名为TryLock,但它是线程安全的,因为您不会在循环中调用CAS,直到成功为止。传统上Lock操作应该阻塞,直到获取成功。

关于volatilestd::atomic the docs指定(关于=运营商):

  

以原子方式为原子变量赋值t。相当于商店(所需)。

然后关于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 ++中几乎没用):

  

在执行的线程中,访问(读取和写入)所有   保证不会相对于每个对象重新排序volatile对象   另外,但这个顺序不能保证被另一个人观察到   线程,因为volatile访问不建立线程间   同步。