Under certain application environments, a class is allowed to have only one instance, which is known as the singleton Pattern. The singleton pattern is divided into the lazy mode, followed by the A Hungry man pattern two kinds. first, the realization of a hungry man mode is Given.
Template <classT>classsingleton{protected: Singleton () {};Private: Singleton (ConstSingleton&) {};//No copyingsingleton&operator=(ConstSingleton&) {};//Prohibit Assignment Statict*m_instance; public: Statict*getinstance ();}; Template<classT>T* singleton<t>:: getinstance () {returnm_instance;} Template<classT>T* Singleton<t>::m_instance =NewT ();
View Code
The constructor of the class is called directly when instantiating a m_instance variable. As the name implies, when a variable is not used, the m_instance is already assigned, like a hungry feeling. This mode is certainly thread-safe in a multithreaded environment, because there is no problem with multithreaded Instantiation.
Let's look at the lazy model
1Template <classT>2 classSingleton3 {4 protected:5 Singleton () {};6 Private:7SingletonConstsingleton&){};8singleton&operator=(Constsingleton&){};9 Statict*m_instance;Ten public: one Statict*getinstance (); a }; - - theTemplate <classT> -t* singleton<t>:: getinstance () - { - if(m_instance = =NULL) + { -M_instance =NewT (); + } a returnm_instance; at } - -Template <classT> -t* singleton<t>::m_instance = NULL;
View Code
In Lazy mode, when the m_instance variable is defined, it is equal to null, and when the getinstance () method is called, it is judged whether to assign a Value. This pattern is not thread-safe because multiple threads calling the GetInstance () method at the same time can cause multiple instances to be produced. To implement thread safety, you must lock.
The following shows the improved code
Template <classT>classsingleton{protected: Singleton () {};Private: Singleton (Constsingleton&){}; Singleton&operator=(Constsingleton&){}; Statict*m_instance; Staticpthread_mutex_t mutex; public: Statict*getinstance ();}; Template<classT>T* singleton<t>:: getinstance () {pthread_mutex_lock (&mutex); if(m_instance = =NULL) {m_instance=NewT (); } pthread_mutex_unlock (&mutex); returnm_instance;} Template<classT>pthread_mutex_t Singleton<t>::mutex =pthread_mutex_initializer;template<classT>T* Singleton<t>::m_instance = NULL;
View Code
It all seems perfect, but the program ape is an animal that is inherently unaware of Contentment. They found that the getinstance () method, each time they came in to lock, will affect Efficiency. however, This is not necessary, so the getinstance () method is improved
Template <class t>T* singleton<t>:: getinstance () { if(m_ Instance = = NULL) { pthread_mutex_lock (&Mutex) ; if (m_instance = = NULL) { New T (); } Pthread_mutex_unlock (&mutex); } return m_instance;}
View Code
This is the so-called "double check lock" Mechanism. however, Some people questioned the implementation of the problem, when the implementation of m_instance = new T (), perhaps the class T has not been initialized to complete, M_instance already have the Value. This leads to another thread that calls the getinstance () method, gets to the m_instance pointer that has not yet been initialized, and, if used, has unintended consequences. In fact, the solution is also very simple, with a local variable transition can be:
Template <class t>T* singleton<t>:: getinstance () { if(m_ Instance = = NULL) { pthread_mutex_lock (&Mutex) ; if (m_instance = = NULL) { Tnew t (); = ptmp; } Pthread_mutex_unlock (&mutex); } return m_instance;}
View Code
Here in the lazy mode, you can also ensure that the thread is Safe.
however, There is another implementation under LINUX. Linux provides a function called Pthread_once (), which guarantees that a function is executed only once in a process. The following is a thread-safe lazy singleton pattern implemented using pthread_once
Template <classT>classsingleton{protected: Singleton () {};Private: Singleton (Constsingleton&){}; Singleton&operator=(Constsingleton&){}; Statict*m_instance; Staticpthread_once_t m_once; public: Static voidInit (); Statict*getinstance ();}; Template<classT>voidSingleton<t>:: Init () {m_instance=NewT ();} Template<classT>T* singleton<t>:: getinstance () {pthread_once (&m_once,init); returnm_instance;} Template<classT>pthread_once_t Singleton<t>::m_once =pthread_once_init;template<classT>T* Singleton<t>::m_instance = NULL;
View Code
Note: the Singleton pattern, The constructor is all protected type, the first is to prevent the direct definition of Singleton class variables, the second is to Singleton class can be inherited. In a project, there may be multiple types to be implemented as singleton, so that only the next singleton class can be inherited. Give a simple example
class test: public singleton<test>{public: test () {}; ~Test () {};}; Test *p = test::getinstance ();
View Code
Transfer from http://www.cnblogs.com/myd620/p/6133420.html
A single-instance mode of C + + for thread safety