[Linux] Singleton Mode-Hungry and Lazy

What is the singleton pattern

Singleton mode is a classic and commonly used. The design pattern of frequent tests.
Design pattern: The big guys give some corresponding solutions for some classic common scenarios

What is a hungry man? What is a lazy man?

The concept is not easy to understand, I will give you an example, everyone should be able to understand

Here is an example of washing dishes.
The first type: wash the dishes immediately after eating, because the next meal can be eaten immediately when the next meal is ready. This is the hungry way: always be prepared.
The second type: put the bowl down after eating and wait for the next meal. Time to wash the dishes, this is the lazy way: prepare when you use it

Did you find the difference between the two? That's right, the core idea of ​​the lazy man mode is "delayed loading", which can optimize the startup speed of the server.
This is similar to the photorealistic copy we talked about in the thread before, because the photorealistic copy also improves the speed of creating the child process.

Hungry man way to achieve singleton mode

template<typename T>
class Singleton{
  static T data;   //提前准备好数据
  public:
  static T* GetInstance()
  {
    return &data;
  }
};

Through the packaged class Singleton above, we can only have one instance of the T object in a process.

The lazy way to achieve singleton mode

template<typename T>
class Singleton{
  static T* inst;
  public:
  static T* GetInstance()
  {
    if(inst==NULL)
    {
      inst=new T(); //用的时候才new一个对象
    }
    return inst;
  }
};

But there is a serious problem here: thread is not safe! !
Because in the first call, if it is called by two threads at the same time, two instances of the T object may be created, which does not meet the requirements of the singleton mode. But there will be no problem with subsequent calls.
Here I make the changes as follows:

Thread safe version: lazy man mode

template<typename T>
class Singleton{
 volatile static T* inst;  //防止被编译器优化
 static std::mutex lock;
  public:
  static T* GetInstance()
  {
    if(inst==NULL)   //双重判断降低锁冲突的概率,提高性能
    {
      lock.lock();
      if(inst==NULL)
      inst=new T(); //用的时候才new一个对象
      lock.unlock();
    }
    return inst;
  }
};

Precautions:

  1. Locked and unlocked position
  2. Double if judgments can reduce lock consumption and avoid unnecessary lock competition
  3. The volatile keyword maintains memory visibility and prevents the compiler from over-optimizing

The contents of Linux basically come to an end here. I have also talked about other contents in the previous blog. Those in need can check it in my column. .
The next blog blogger is ready to summarize the network-related knowledge, don’t forget to follow the blogger~

Guess you like

Origin blog.csdn.net/ly_6699/article/details/98471185