#include <iostream> #include <mutex> #include <condition_variable> #include <memory> template<typename T> class ThreadSafeQueue { private: struct Node { std::shared_ptr<T> p_data; //指向数据块 std::unique_ptr<Node> next; }; std::unique_ptr<Node> head;//头 Node* tail; //尾 mutable std::mutex mtx_head; mutable std::mutex mtx_tail; std::condition_variable con_push; //数据入队通知 public: ThreadSafeQueue():head(new Node),tail(head.get()) {} ~ThreadSafeQueue() { while(head){ head = std::move(head->next); } tail = nullptr; } ThreadSafeQueue(const ThreadSafeQueue&)=delete; ThreadSafeQueue& operator=(const ThreadSafeQueue&)=delete; private: Node* get_tail() { std::lock_guard<std::mutex> lock_tail(mtx_tail); return tail; } std::unique_ptr<Node> pop_head() { std::unique_ptr<Node> old_head=std::move(head); head=std::move(old_head->next); return old_head; } std::unique_ptr<Node> try_pop_head(T& value) { std::lock_guard<std::mutex> head_lock(mtx_head); if(head.get()==get_tail()) { return std::unique_ptr<Node>(); } value=std::move(*head->p_data); return pop_head(); } std::unique_ptr<Node> wait_pop_head(T& value) { std::unique_lock<std::mutex> head_lock(mtx_head); con_push.wait(head_lock,[&]{return head.get()!=get_tail();}); value=*head->p_data; return pop_head(); } public: void push(T value) { //构造数据块 std::shared_ptr<T> new_data(std::make_shared<T>(value)); //构造新节点 std::unique_ptr<Node> new_node(new Node); //会被当做新的虚拟节点 { //操作尾部指针,先加锁 std::lock_guard<std::mutex> tail_lock(mtx_tail); tail->p_data = new_data; //数据块挂载 tail->next = std::move(new_node); tail = (tail->next).get();//指向新的虚拟节点 } con_push.notify_one(); } bool try_pop(T& value) { std::unique_ptr<Node> const old_head=try_pop_head(value); return old_head != nullptr; } void wait_and_pop(T& value) { std::unique_ptr<Node> const old_head=wait_pop_head(value); } };
标签:std,head,队列,value,tail,unique,ptr From: https://www.cnblogs.com/fchy822/p/18110841