4

我知道互斥锁也可以从这里带来作为内存屏障的效果:互斥锁可以替换内存屏障,但是我总是看到在下面的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;
 }
4

1 回答 1

1

如果可以使用 C++11,则无需编写自己的保护程序。

正如这里也提到的,所有需要的东西都已经是 C++11 的一部分。从那里复制:

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

如果在变量初始化时控制同时进入声明,则并发执行将等待初始化完成。— § 6.7 [stmt.dcl] p4

Singleton& GetInstance() {
  static Singleton s;
  return s;
}

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

于 2020-10-28T15:52:03.740 回答