队列
#include <iostream> #include <mutex> #include <condition_variable> #include <thread> 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); } }; void producer(ThreadSafeQueue<int>& queue, int n) { for (int i = 0; i < n; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟生产过程中的延迟 queue.push(i); std::cout << "Produced: " << i << std::endl; } } void consumer_try_pop(ThreadSafeQueue<int>& queue, int n) { for (int i = 0; i < n; ++i) { int value; if (queue.try_pop(value)) { std::cout << "Consumer (try_pop): " << value << std::endl; } else { std::cout << "Queue is empty" << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 模拟消费过程中的延迟 } } void consumer_wait_and_pop(ThreadSafeQueue<int>& queue, int n) { for (int i = 0; i < n; ++i) { int value; queue.wait_and_pop(value); std::cout << "Consumer (wait_and_pop): " << value << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 模拟消费过程中的延迟 } } int main() { ThreadSafeQueue<int> queue; const int num_produce = 100; const int num_consume = 25; std::thread producer_thread1(producer, std::ref(queue), num_produce); //std::thread consumer_try_pop_thread1(consumer_try_pop, std::ref(queue), num_consume); //std::thread consumer_try_pop_thread2(consumer_try_pop, std::ref(queue), num_consume); std::thread consumer_wait_and_pop_thread1(consumer_wait_and_pop, std::ref(queue), num_consume); std::thread consumer_wait_and_pop_thread2(consumer_wait_and_pop, std::ref(queue), num_consume); std::thread consumer_wait_and_pop_thread3(consumer_wait_and_pop, std::ref(queue), num_consume); std::thread consumer_wait_and_pop_thread4(consumer_wait_and_pop, std::ref(queue), num_consume); producer_thread1.join(); //consumer_try_pop_thread1.join(); //consumer_try_pop_thread2.join(); consumer_wait_and_pop_thread1.join(); consumer_wait_and_pop_thread2.join(); consumer_wait_and_pop_thread3.join(); consumer_wait_and_pop_thread4.join(); return 0; }