#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;
}