-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsingleton.h
More file actions
187 lines (161 loc) · 3.34 KB
/
singleton.h
File metadata and controls
187 lines (161 loc) · 3.34 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef SINGLETON_H
#define SINGLETON_H
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
template <class T>
class Queue {
protected:
// Data
std::queue<T> _queue;
typename std::queue<T>::size_type _size_max;
// Thread gubbins
std::mutex _mutex;
std::condition_variable _fullQue;
std::condition_variable _empty;
// Exit
// 原子操作
std::atomic_bool _quit; //{ false };
std::atomic_bool _finished; // { false };
public:
Queue() :_size_max(100) {
_quit = ATOMIC_VAR_INIT(false);
_finished = ATOMIC_VAR_INIT(false);
}
Queue(const size_t size_max) :_size_max(size_max) {
_quit = ATOMIC_VAR_INIT(false);
_finished = ATOMIC_VAR_INIT(false);
}
bool push(T& data)
{
std::unique_lock<std::mutex> lock(_mutex);
while (!_quit && !_finished)
{
if (_queue.size() < _size_max)
{
_queue.push(std::move(data));
//_queue.push(data);
_empty.notify_all();
return true;
}
else
{
// wait的时候自动释放锁,如果wait到了会获取锁
_fullQue.wait(lock);
}
}
return false;
}
bool pop(T &data)
{
std::unique_lock<std::mutex> lock(_mutex);
while (!_quit)
{
if (!_queue.empty())
{
//data = std::move(_queue.front());
data = _queue.front();
_queue.pop();
_fullQue.notify_all();
return true;
}
else if (_queue.empty() && _finished)
{
return false;
}
else
{
_empty.wait(lock);
}
}
return false;
}
// The queue has finished accepting input
void finished()
{
_finished = true;
_empty.notify_all();
}
void quit()
{
_quit = true;
_empty.notify_all();
_fullQue.notify_all();
}
int length()
{
return static_cast<int>(_queue.size());
}
};
//--------------------------------------------------------------
template <class T>
class Singleton
{
private:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
public:
template <typename... Args>
static T* instance(Args&&... args)
{
std::call_once(_flag, [&](){
_instance = new T(std::forward<Args>(args)...);
});
return _instance;
}
static void destroy()
{
if (_instance)
{
delete _instance;
_instance = NULL;
}
}
private:
static T* _instance;
static std::once_flag _flag;
};
template <class T>
T* Singleton<T>::_instance = NULL;
template <class T>
std::once_flag Singleton<T>::_flag;
//--------------------------------------------------------------
template <class T>
class Singleton_HW
{
private:
Singleton_HW() = default;
~Singleton_HW() = default;
Singleton_HW(const Singleton_HW&) = delete;
Singleton_HW& operator=(const Singleton_HW&) = delete;
public:
template <typename... Args>
static T* instance(Args&&... args)
{
std::call_once(_flag, [&]() {
_instance = new T(std::forward<Args>(args)...);
});
return _instance;
}
static void destroy()
{
if (_instance)
{
delete _instance;
_instance = NULL;
}
}
private:
static T* _instance;
static std::once_flag _flag;
};
template <class T>
T* Singleton_HW<T>::_instance = NULL;
template <class T>
std::once_flag Singleton_HW<T>::_flag;
#endif // SINGLETON_H