1
2#include <queue>
3#include <memory>
4#include <mutex>
5#include <condition_variable>
6template<typename T>
7class threadsafe_queue
8{
9private:
10 mutable std::mutex mut; ❶
11 std::queue<T> data_queue;
12 std::condition_variable data_cond;
13public:
14 threadsafe_queue()
15 {}
16 threadsafe_queue(threadsafe_queue const& other)
17 {
18 std::lock_guard<std::mutex> lk(other.mut);
19 data_queue=other.data_queue;
20 }
21 void push(T new_value)
22 {
23 std::lock_guard<std::mutex> lk(mut);
24 data_queue.push(new_value);
25 data_cond.notify_one();
26 }
27 void wait_and_pop(T& value)
28 {
29 std::unique_lock<std::mutex> lk(mut);
30 data_cond.wait(lk,[this]{return !data_queue.empty();});
31 value=data_queue.front();
32 data_queue.pop();
33 }
34 std::shared_ptr<T> wait_and_pop()
35 {
36 std::unique_lock<std::mutex> lk(mut);
37 data_cond.wait(lk,[this]{return !data_queue.empty();});
38 std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
39 data_queue.pop();
40 return res;
41 }
42 bool try_pop(T& value)
43 {
44 std::lock_guard<std::mutex> lk(mut);
45 if(data_queue.empty())
46 return false;
47 value=data_queue.front();
48 data_queue.pop();
49 return true;
50 }
51 std::shared_ptr<T> try_pop()
52 {
53 std::lock_guard<std::mutex> lk(mut);
54 if(data_queue.empty())
55 return std::shared_ptr<T>();
56 std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
57 data_queue.pop();
58 return res;
59 }
60 bool empty() const
61 {
62 std::lock_guard<std::mutex> lk(mut);
63 return data_queue.empty();
64 }
65};
66
67