C ++ singleton pattern implementation C ++ singleton pattern (lazy, starving mode)

C ++ singleton pattern (lazy, starving mode)

In C ++ singleton pattern (including smart pointers in C ++. 11)

 

Starving mode:

class CSingleton     
{     
Private :     
    CSingleton ()       
    {     
    }     
public :    
     static CSingleton * the GetInstance ()     
    {     
        static CSingleton instance;     
         return & instance;     
    }     
};
---------------- 
Copyright Notice: This CSDN blogger for the original article "zhanghuaichao", and follow CC 4.0 BY- SA copyright agreement, reproduced, please attach the original source link and this statement. 
Original link: HTTPS: // blog.csdn.net/zhanghuaichao/article/details/79459130

 

Lazy mode multithreading

class Singleton  
{  
private:  
    static Singleton* m_instance;  
    Singleton(){}  
public:  
    static Singleton* getInstance();  
};  
  
Singleton* Singleton::getInstance()  
{  
    if(NULL == m_instance)  
    {  
        Lock();//借用其它类来实现,如boost  
        if(NULL == m_instance)  
        {  
            m_instance = new Singleton;  
        }  
        UnLock();  
    }  
    return m_instance;   
} 
---------------- 
Disclaimer: This article is CSDN blogger "zhanghuaichao 'original article, follow the CC 4.0 BY- SA copyright agreement, reproduced, please attach the original source link and this statement. 
Original link: HTTPS: // blog.csdn.net/zhanghuaichao/article/details/79459130

 

Lazy: name suggests, not a last resort would not have to instantiate the class, that is to say when the first instance of the class will be used to instantiate. Corresponding thereto are starving single embodiment. (Note that lazy itself is not thread-safe, as examples)

Han hungry: hungry will certainly be hungry. Therefore, when the singleton class definition to instantiated. (Itself a thread-safe, as examples)

About how to choose the lazy and hungry man mode:

Features and options:

  Lazy: In the small number of visits, the use of lazy achieve. This is the time for space.

  Hungry man: Due to thread synchronization, so the visit than the larger, or threads may access the relatively long time, the use of a hungry man to achieve, you can achieve better performance. This is space for time.

3, the singleton type implemented starving

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <process.h>
#include <windows.h>
using  namespace  std;
 
class  Singelton{
private :
     Singelton(){
         m_count ++;
         printf ( "Singelton begin\n" );
         Sleep(1000);                             // 加sleep为了放大效果
         printf ( "Singelton end\n" );
     }
     static  Singelton *single;
public :
     static  Singelton *GetSingelton();
     static  void  print();
     static  int  m_count;
};
// 饿汉模式的关键:初始化即实例化
Singelton *Singelton::single =  new  Singelton;
int  Singelton::m_count = 0;
 
Singelton *Singelton::GetSingelton(){
     // 不再需要进行实例化
     //if(single == nullptr){
     //    single = new Singelton;
     //}
     return  single;
}
 
void  Singelton::print(){
     cout<<m_count<<endl;
}
// 回调函数
void  threadFunc( void  *p){
     DWORD  id = GetCurrentThreadId();         // 获得线程id
      cout<<id<<endl;
     Singelton::GetSingelton()->print();       // 构造函数并获得实例,调用静态成员函数
}
 
int  main( int  argc,  const  char  * argv[]) {
     int  threadNum = 3;
     HANDLE  threadHdl[100];
     
     // 创建3个线程
     for ( int  i = 0; i<threadNum; i++){
         threadHdl[i] = ( HANDLE )_beginthread(threadFunc, 0,  nullptr );
     }
     
     // 让主进程等待所有的线程结束后再退出
     for ( int  i = 0; i<threadNum; i++){
         WaitForSingleObject(threadHdl[i], INFINITE);
     }
     cout<< "main" <<endl;                  // 验证主进程是否是最后退出
     return  0;
}

  operation result:

4, thread-safe implementations of lazy single cases

Hungry man style would be a waste of memory space and advance our resources, if the project requires that we use to go to instantiate instances when you still need to use lazy man.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class  singleton
{
protected :
     singleton()
     {
         // 初始化
         pthread_mutex_init(&mutex);
     }
private :
     static  singleton* p;
public :
     static  pthread_mutex_t mutex;
     static  singleton* initance();
};
 
pthread_mutex_t singleton::mutex;
singleton* singleton::p = NULL;
singleton* singleton::initance()
{
     if  (p == NULL)
     {
         // 加锁
         pthread_mutex_lock(&mutex);
         if  (p == NULL)
             p =  new  singleton();
         pthread_mutex_unlock(&mutex);
     }
     return  p;
}

  需要注意的是:上面进行的两次if(p == NULL)的检查,因为当获得了实例之后,有了外层的判断之后,就不会再进入到内层判断,即不会再进行lock以及unlock的操作。

Guess you like

Origin www.cnblogs.com/sylar5/p/11520505.html