C + + single case mode

Source: Internet
Author: User
Tags mutex

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.