使用互斥锁时,C++ 单例是否需要内存屏障?

wod*_*der 5 c++ memory-barriers stdmutex

我从这里知道互斥锁也可以带来内存屏障的效果:Can mutex Replace Memory Barrier,但我总是看到在 C++ 单例示例中使用了内存屏障,如下所示,内存屏障是不必要的吗?

Singleton* Singleton::getInstance() {
     Singleton* tmp = m_instance.load(std::memory_order_relaxed);
     std::atomic_thread_fence(std::memory_order_acquire);        
     if (tmp == nullptr) {
         std::lock_guard<std::mutex> lock(m_mutex);               // using mutex here
         tmp = m_instance.load(std::memory_order_relaxed);
         if (tmp == nullptr) {
             tmp = new Singleton;
             assert(tmp != nullptr);    
             std::atomic_thread_fence(std::memory_order_release); // using memory barrier here
             m_instance.store(tmp, std::memory_order_relaxed);
         }
     }
     return tmp;
 }
Run Code Online (Sandbox Code Playgroud)

Kla*_*aus 1

如果你会使用C++11,你就不需要自己编写保护程序。

\n

正如此处所引用的,所有需要的东西都已经是 C++11 的一部分。从那里复制的:

\n
\n

对于单例模式,不需要双重检查锁定:

\n
\n
\n

如果在变量初始化时控制同时进入声明,则并发执行应等待初始化完成。\n\xe2\x80\x94\xe2\x80\x89\xc2\xa7 6.7 [stmt.dcl] p4

\n
\n
Singleton& GetInstance() {\n  static Singleton s;\n  return s;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该实现将提供内存屏障或其他任何东西来保护您的并发访问。因此,请保持简单,如示例所示!

\n