1 This article mainly discusses under the multi-threading under the single example pattern realization:
The first is the double check implementation: This mode can meet the multi-threaded environment, only one instance is generated.
Template<typename t>classDclsingleton { Public: Statict&getinstance () {if(NULL = =value_) {Mutexguard mg (mutex_); if(NULL = =value_) {value_ = new T; } } return*Value_; } protected: Dclsingleton () {std::cout<<"Dclsingleton Constuctor called"<<Std::endl;} Dclsingleton (ConstDclsingleton &DCL) {}Private: Statict*Value_; StaticMutex mutex_; };
But this implementation exists in addition to the bug, the problem is: Value_ = new T; On "Self-cultivation of programmers," said:
This code is problematic, and the source of the problem is the random execution of the CPU. New in C + + contains two steps.
(1) Allocating memory
(2) Call constructor
So value_ = new T; There are actually three steps involved:
(1) Allocating memory
(2) Call the constructor on the location where memory is allocated
(3) The memory address is assigned to Value_;
In these three steps, (2), (3) Two steps can be reversed, that is, may occur, first execute (3) This is value_ is already not NULL, when another concurrent call to GetInstance, if the value_! = NULL then returns, but has not yet called the constructor. So when you use this pointer, it causes a crash.
It is necessary to ensure (2), (3) The order of execution, usually need to add a memory barrier, to ensure that (2) after the execution, and then execute (3)
Here I have added __sync_synchronize (); After the implementation is this:
Statict&getinstance () {if(NULL = =value_) {Mutexguard mg (mutex_); if(NULL = =value_) {T* tmp = static_cast<t*> (operator New(sizeof(T))); New(TMP) T (); __sync_synchronize ();Value_ =tmp; } } return*Value_; }
This will ensure that the multi-threaded environment security, but also ensure that the above problems will not occur.
2. Add a memory Barrier example code: dcl_single.h
#ifndef __dcl_single_h#define__dcl_single_h#include<iostream>namespaceyl{classMutex { Public: Mutex () {Pthread_mutex_init (&mutex_, NULL); } ~Mutex () {Pthread_mutex_destroy (&mutex_); } Public: voidLock () {Pthread_mutex_lock (&mutex_); } voidUnLock () {Pthread_mutex_unlock (&mutex_); } Private: pthread_mutex_t mutex_; }; classMutexguard { Public: Mutexguard (Mutex&m): Mutex_ (m) {mutex_. Lock (); } ~Mutexguard () {mutex_. UnLock (); } Private: Mutex mutex_; }; Template<typename t>classDclsingleton { Public: Statict&getinstance () {if(NULL = =value_) {Mutexguard mg (mutex_); if(NULL = =value_) {T* tmp = static_cast<t*> (operator New(sizeof(T))); New(TMP) T (); __sync_synchronize (); Value_=tmp; } } return*Value_; } protected: Dclsingleton () {std::cout<<"Dclsingleton Constuctor called"<<Std::endl;} Dclsingleton (ConstDclsingleton &DCL) {}Private: Statict*Value_; StaticMutex mutex_; }; Template<typename t>T* Dclsingleton<t>::value_ =NULL; Template<typename t>Mutex Dclsingleton<T>:: mutex_;}#endif
View Code
SingletonTest.cpp
#include"dcl_single.h"#include<iostream>namespaceyl{classMGRSG: PublicDclsingleton<mgrsg> { Private: FriendclassDclsingleton <MgrSg>; MGRSG () {std::cout<<"Mgrsg:constructor called"<<Std::endl;} ~MGRSG () {std::cout <<"Mgrsg:desconstructor called"<<Std::endl;} Public: voidprint () {std::cout<<"Print called"<<Std::endl; } };}intMain (void){ using namespaceyl; Mgrsg::getinstance (). print (); return 0;}
3. You can also use Pthread_once under UNIX to implement a singleton mode:
Template <typename t>classMysingleton { Public: StaticT &getinstance () {pthread_once (&ponce_, &mysingleton::init); return*instance; } protected: Mysingleton () {} Mysingleton (Constmysingleton&) {} Private: Static voidinit () {instance=NewT (); } Private: Staticpthread_once_t Ponce_; StaticS Minstance; }; Template<typename t>pthread_once_t Mysingleton<t>::p once_ =Pthread_once_init; Template<typename t>T*mysingleton<t>::instance =nullptr;}
4. My own experience is the above two cases, if you want to understand more comprehensive, can refer to the following:
Http://www.cnblogs.com/liyuan989/p/4264889.html
5. The level is limited, hope to timely point out errors. Thank you
C + + single case mode