-
Notifications
You must be signed in to change notification settings - Fork 63
/
MTQueue.h
71 lines (60 loc) · 1.6 KB
/
MTQueue.h
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
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
template <class T>
class MTQueue {
std::condition_variable m_cv;
std::mutex m_mtx;
std::vector<T> m_arr;
public:
T pop() {
std::unique_lock lck(m_mtx);
m_cv.wait(lck, [this] { return !m_arr.empty(); });
T ret = std::move(m_arr.back());
m_arr.pop_back();
return ret;
}
auto pop_hold() {
std::unique_lock lck(m_mtx);
m_cv.wait(lck, [this] { return !m_arr.empty(); });
T ret = std::move(m_arr.back());
m_arr.pop_back();
return std::pair(std::move(ret), std::move(lck));
}
void push(T val) {
std::unique_lock lck(m_mtx);
m_arr.push_back(std::move(val));
m_cv.notify_one();
}
void push_many(std::initializer_list<T> vals) {
std::unique_lock lck(m_mtx);
std::copy(
std::move_iterator(vals.begin()),
std::move_iterator(vals.end()),
std::back_insert_iterator(m_arr));
m_cv.notify_all();
}
};
int main() {
MTQueue<int> foods;
std::thread t1([&] {
for (int i = 0; i < 2; i++) {
auto food = foods.pop();
std::cout << "t1 got food:" << food << std::endl;
}
});
std::thread t2([&] {
for (int i = 0; i < 2; i++) {
auto food = foods.pop();
std::cout << "t2 got food:" << food << std::endl;
}
});
foods.push(42);
foods.push(233);
foods.push_many({666, 4399});
t1.join();
t2.join();
return 0;
}