woder
woder

Reputation: 805

Is c++ singleton need memory barrier while using mutex?

I have known that mutex can also bring the effect as memory barrier from here: Can mutex replace memory barriers, but I always see there is an memory barrier using in c++ singleton example as below, is the memory barrier unnecessary?

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;
 }

Upvotes: 5

Views: 311

Answers (1)

Klaus
Klaus

Reputation: 25663

If you can use C++11, you do not need to program your own protection.

As also referenced here, all the needed stuff is already part of C++11. Copied from there:

For the singleton pattern, double-checked locking is not needed:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. — § 6.7 [stmt.dcl] p4

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

The implementation will provide a memory barrier or whatever to protect your concurrent access. So keep it simple as given in the example!

Upvotes: 1

Related Questions