Patrón de diseño (7) Patrón singleton

Introducción al modo singleton

En el modo singleton, en el global, solo puede haber una instancia de clase del modo de interés simple y se proporciona un punto de acceso global para acceder a esta instancia única.
Se puede observar que las características del modelo de interés simple son

  • Solo puede haber una instancia de esta clase
  • Debes crear esta instancia tú mismo
  • Debe proporcionar esta instancia a todo el sistema usted mismo

Estructura del modo singleton

La estructura del patrón singleton es muy simple, contiene solo una clase, la clase singleton. Para evitar la creación de varios objetos, su constructor debe ser privado.
Por otro lado, para proporcionar un punto de acceso global para acceder a la instancia única, la clase singleton proporciona un método público getInstance para devolver la instancia.
Inserte la descripción de la imagen aquí

Hilo único

El constructor de esta clase es privado y contiene una variable miembro estática m_instance y una función miembro GetInstance (). Utilice GetInstance () para devolver el puntero de esta clase.

Último ejemplo:

#include<iostream>
#include<thread>
#include<mutex>
#include<algorithm>

using namespace std;
 
class MyCAS
{
    
    
public:
	static MyCAS *GetInstance()
	{
    
    
		if (m_instance == NULL)
		{
    
    
			m_instance = new MyCAS();
      		cout << "MyCAS Set" << endl;
		}
    
		return m_instance;
	}	

private:
	MyCAS() {
    
    }

	static MyCAS *m_instance;
};
 
MyCAS *MyCAS::m_instance = NULL;

int main()
{
    
    
	MyCAS *ptr1 = MyCAS::GetInstance();
  	MyCAS *ptr2 = MyCAS::GetInstance();

	return 0;
}

Se puede ver que el constructor es privado, por lo que el modo singleton solo se puede instanciar dentro de la clase. Al mismo tiempo, la instancia del objeto de instancia es estática estática global, por lo que se garantiza que la instancia solo se puede crear una vez.

Multihilo

Ahora considere la siguiente situación de múltiples subprocesos, m_instance está vacío, si dos subprocesos ejecutan la función GetInstance () al mismo tiempo, entonces m_instance = new MyCAS () puede ejecutarse varias veces y aparecerán varios objetos en el programa, lo que es obviamente contrario a la intención original del patrón singleton.

#include <iostream>
#include <thread>
#include <mutex>
#include <algorithm>

using namespace std;

mutex resource_mutex;

class MyCAS
{
    
    
public:
  static MyCAS *GetInstance()
  {
    
    
    // double check
    if (m_instance == NULL)
    {
    
    
      unique_lock<mutex> guard(resource_mutex);
      if (m_instance == NULL)
      {
    
    
        m_instance = new MyCAS();
        cout << " MyCAS Set ! " << endl;
      }
    }
    return m_instance;
  }

private:
  MyCAS() {
    
    }
  static MyCAS *m_instance;
};

MyCAS *MyCAS::m_instance = NULL;

void MyFunc()
{
    
    
  cout << " Thread Start " << endl;
  MyCAS *ptr = MyCAS::GetInstance();
  cout << " Thread Stop " << endl;
}

int main()
{
    
    
  thread obj1(MyFunc);
  thread obj2(MyFunc);

  obj1.join();
  obj2.join();

  return 0;
}

call_once ()

El bit de bandera flag_once se establece en call_once (). Al registrar este bit de bandera, se determina si la función ha sido llamada, asegurando así que la función solo se llame una vez. Cuando otro hilo llama a la función call_once () nuevamente, la función ya no se ejecutará.

#include <iostream>
#include <thread>
#include <mutex>
#include <algorithm>

using namespace std;

once_flag g_flag;

class MyCAS
{
    
    
public:
  static void CreatInstance()
  {
    
    
    m_instance = new MyCAS();
    cout << " MyCAS Set " << endl;
  }

  static MyCAS *GetInstance()
  {
    
    
    call_once(g_flag, CreatInstance);
    return m_instance;
  }

private:
  MyCAS() {
    
    }
  static MyCAS *m_instance;
};

MyCAS *MyCAS::m_instance = NULL;

void MyFunc()
{
    
    
  cout << " Thread Start " << endl;
  MyCAS *ptr = MyCAS::GetInstance();
  cout << " Thread Stop " << endl;
}

int main()
{
    
    
  thread obj1(MyFunc);
  thread obj2(MyFunc);

  obj1.join();
  obj2.join();
  
  return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_24649627/article/details/115213148
Recomendado
Clasificación