efficient thread-safe singleton in C++

前端 未结 9 1551
醉话见心
醉话见心 2020-11-28 18:30

The usual pattern for a singleton class is something like

static Foo &getInst()
{
  static Foo *inst = NULL;
  if(inst == NULL)
    inst = new Foo(...);
         


        
相关标签:
9条回答
  • 2020-11-28 18:48

    ACE singleton implementation uses double-checked locking pattern for thread safety, you can refer to it if you like.

    You can find source code here.

    0 讨论(0)
  • 2020-11-28 18:49

    Herb Sutter talks about the double-checked locking in CppCon 2014.

    Below is the code I implemented in C++11 based on that:

    class Foo {
    public:
        static Foo* Instance();
    private:
        Foo() {}
        static atomic<Foo*> pinstance;
        static mutex m_;
    };
    
    atomic<Foo*> Foo::pinstance { nullptr };
    std::mutex Foo::m_;
    
    Foo* Foo::Instance() {
      if(pinstance == nullptr) {
        lock_guard<mutex> lock(m_);
        if(pinstance == nullptr) {
            pinstance = new Foo();
        }
      }
      return pinstance;
    }
    

    you can also check complete program here: http://ideone.com/olvK13

    0 讨论(0)
  • 2020-11-28 18:49

    Does TLS work here? https://en.wikipedia.org/wiki/Thread-local_storage#C_and_C++

    For example,

    static _thread Foo *inst = NULL;
    static Foo &getInst()
    {
      if(inst == NULL)
        inst = new Foo(...);
      return *inst;    
     }
    

    But we also need a way to delete it explicitly, like

    static void deleteInst() {
       if (!inst) {
         return;
       }
       delete inst;
       inst = NULL;
    }
    
    0 讨论(0)
  • 2020-11-28 18:50

    If you are using C++11, here is a right way to do this:

    Foo& getInst()
    {
        static Foo inst(...);
        return inst;
    }
    

    According to new standard there is no need to care about this problem any more. Object initialization will be made only by one thread, other threads will wait till it complete. Or you can use std::call_once. (more info here)

    0 讨论(0)
  • 2020-11-28 18:52

    Use pthread_once, which is guaranteed that the initialization function is run once atomically.

    (On Mac OS X it uses a spin lock. Don't know the implementation of other platforms.)

    0 讨论(0)
  • 2020-11-28 19:06

    TTBOMK, the only guaranteed thread-safe way to do this without locking would be to initialize all your singletons before you ever start a thread.

    0 讨论(0)
提交回复
热议问题