单例模式(懒汉式和饿汉式)及如何实现线程安全

单例模式有两种:懒汉式和饿汉式。

1 #include 
2
3 using namespace std;
4
5
6 //  保证在整个程序运行期间,最多只能有一个对象实例
7
8
9 //  懒汉式
10 // 1 、构造函数私有化
11 // 2 、写一个静态函数获取对象指针
12 // 3 、有一个静态成员变量,保存对象指针
13 class Singleton
14 {
15 private:
16 Singleton()
17 {
18
19 }
20
21 public:
22 static Singleton* GetInstance()
23 {
24 if (m_instance == NULL)
25 m_instance = new Singleton;
26
27 return m_instance;
28 }
29
30 private:
31 static Singleton *m_instance;
32 };
33
34 Singleton *Singleton::m_instance = NULL;
35
36 int main1()
37 {
38 Singleton* pa = Singleton::GetInstance();
39 Singleton* pb = Singleton::GetInstance();
40 Singleton* pc = Singleton::GetInstance();
41
42 printf("%p\n", pa);
43 printf("%p\n", pb);
44 printf("%p\n", pc);
45
46 return 0;
47 }
48
49
50 //  恶汉式
51 class Singleton1
52 {
53 private:
54 Singleton1()
55 {
56
57 }
58
59 public:
60 static Singleton1* GetInstance()
61 {
62 return m_instance;
63 }
64
65 private:
66 static Singleton1 *m_instance;
67 };
68 Singleton1 *Singleton1::m_instance = new Singleton1;
69
70 int main()
71 {
72 Singleton1* pa = Singleton1::GetInstance();
73 Singleton1* pb = Singleton1::GetInstance();
74 Singleton1* pc = Singleton1::GetInstance();
75
76 printf("%p\n", pa);
77 printf("%p\n", pb);
78 printf("%p\n", pc);
79
80 return 0;
81 }
82

饿汉式因为对象已经初始化了,所以线程不会误操作,但是懒汉式如何多个线程同时调用构造,如何实现线程安全呢?

1#include 
2 #include 
3 using namespace std;
4
5 class Singleton
6 {
7 private:
8 Singleton()
9 {
10 sleep(5);
11 printf (" 构造函数被调用 \n");
12 }
13
14 public:
15 static Singleton* GetInstance()
16 {
17 // printf (" 获取对象 \n");
18
19 if (m_instance == NULL)
20 {
21 pthread_mutex_lock(&m_lock); //  上锁
22
23 if (m_instance == NULL)
24 m_instance = new Singleton;
25
26 pthread_mutex_unlock(&m_lock); //  解锁
27 }
28
29 return m_instance;
30 }
31
32 private:
33 static pthread_mutex_t m_lock; //  互斥锁
34 static Singleton *m_instance;
35 };
36 Singleton *Singleton::m_instance = NULL;
37 pthread_mutex_t Singleton::m_lock = PTHREAD_MUTEX_INITIALIZER;
38
39
40
41 void *worker(void* arg)
42 {
43 Singleton* p = Singleton::GetInstance();
44 }
45
46 int main()
47 {
48 for (int i = 0; i < 10; i++)
49 {
50 pthread_t id;
51 pthread_create(&id, NULL, worker, NULL);
52 pthread_detach(id); //  线程分离
53 }
54
55 pthread_exit(NULL);
56
57 return 0;
58 }
59
60

 

你可能感兴趣的:(C++,linux)