-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsyncqueue.h
More file actions
142 lines (123 loc) · 2.58 KB
/
syncqueue.h
File metadata and controls
142 lines (123 loc) · 2.58 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
#ifndef SYNCQUEUE_H
#define SYNCQUEUE_H
#include <list>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <iostream>
//类模板不能将声明和实现分开在两个文件中
template<typename T>
class SyncQueue
{
public:
SyncQueue(int maxSize) : m_maxSize(maxSize), m_stopRun(false)
{
std::cout << "SyncQueue Construction" << std::endl;
}
~SyncQueue()
{
std::cout << "SyncQueue Destruction" << std::endl;
}
void Put(const T&t)
{
Add(t);
}
void Put(T&&t)
{
Add(std::forward<T>(t));
}
template<typename F>
void Add(F&&f)
{
std::unique_lock<std::mutex> locker(m_mutex);
m_notFull.wait(locker, [this](){
return m_stopRun || NotFull();
});
if (m_stopRun)
{
return;
}
m_list.push_back(std::forward<F>(f));
m_notEmpty.notify_one();
}
//取任务,每次将list中的所有任务全部取出
void Get(std::list<T> &list)
{
std::unique_lock<std::mutex> locker(m_mutex);
m_notEmpty.wait(locker, [this](){
return m_stopRun || NotEmpty();
});
if (m_stopRun)
{
return;
}
list = std::move(m_list);
m_notFull.notify_one();
}
//取任务,每次将list中头部的一个任务取出
void Get(T&t)
{
std::unique_lock<std::mutex> locker(m_mutex);
m_notEmpty.wait(locker, [this](){
return m_stopRun || NotEmpty();
});
if (m_stopRun)
{
return;
}
t = m_list.front();
m_list.pop_front();
m_notFull.notify_one();
}
bool Empty()
{
std::lock_guard<std::mutex> locker(m_mutex);
return m_list.empty();
}
bool Full()
{
std::lock_guard<std::mutex> locker(m_mutex);
return m_list.size() == m_maxSize;
}
bool NotEmpty() const
{
bool empty = m_list.empty();
if (empty)
{
std::cout << "缓冲区空了,需要等待" << std::endl;
}
return !empty;
}
bool NotFull() const
{
bool full = m_list.size() >= m_maxSize;
if (full)
{
std::cout << "缓冲区满了,需要等待" << std::endl;
}
return !full;
}
void StopList()
{
{
std::lock_guard<std::mutex> locker(m_mutex);
//同步队列停止
m_stopRun = true;
}
m_notFull.notify_all();
m_notEmpty.notify_all();
}
private:
std::list<T> m_list; // 缓冲区
// 互斥量和条件变量结合起来使用
std::mutex m_mutex; // 互斥量
std::condition_variable m_notEmpty; // 不为空的条件变量
std::condition_variable m_notFull; // 不为满的条件变量
// 同步队列的最大值
int m_maxSize;
// 同步队列是否停止
// TRUE表示同步队列停止运行
// FALSE表示同步队列没有停止运行
bool m_stopRun;
};
#endif