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

7 c++ multithreading thread-safety c++11

这段代码是否安全?我应该在函数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;}
};
Run Code Online (Sandbox Code Playgroud)

Tud*_*dor 8

是的,它是线程安全的,虽然你可以重命名Lock为,TryLock因为你没有在循环中调用CAS,直到它成功.传统上Lock操作应该阻止,直到获得成功.

至于volatile,该文档std::atomic规定(关于=运算符):

原子上为原子变量赋值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++中大多无用):

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

  • 回复:"挥发性保证比上述保证更弱".确实:它在标准C++中没有任何保证.它与编译器的文档说的一样有用. (2认同)