代码如下——
#pragma once
#include <queue>
#include <pthread.h>
const int BLOCKING_QUEUE_DEFAULT_CAPACITY = 32;
template<class T>
class BlockingQueue
{
private:
using self_t = BlockingQueue<T>;
public:
using size_type=typename std::queue<T>::size_type;
public:
BlockingQueue(size_type capacity = BLOCKING_QUEUE_DEFAULT_CAPACITY)
:capacity_(capacity)
{
pthread_mutex_init(&mtx_,nullptr);
pthread_cond_init(¬_full_,nullptr);
pthread_cond_init(¬_empty_,nullptr);
}
// 禁用拷贝和拷贝赋值
BlockingQueue(const self_t&) = delete;
self_t&operator = (const self_t&) = delete;
//禁用移动构造和赋值
BlockingQueue(self_t&&other)noexcept = delete;
self_t operator = (self_t&&other)noexcept = delete;
//析构函数
virtual~BlockingQueue()
{
this->capacity_ = BLOCKING_QUEUE_DEFAULT_CAPACITY;
pthread_mutex_destroy(&mtx_);
pthread_cond_destroy(¬_full_);
pthread_cond_destroy(¬_empty_);
}
private:
bool is_empty()const noexcept
{
return bq_.size()==0;
}
bool is_full()const noexcept
{
return this->bq_.size()==this->capacity_;
}
public:
void push(const T &val)
{
// 先申请mtx
pthread_mutex_lock(&mtx_);
// 等待条件 满足
while(this->is_full())
{
// 释放锁并等待条件
pthread_cond_wait(¬_full_,&mtx_);
}
// 条件满足并已加锁
bq_.push(val);
//唤醒一个消费者 告诉消费者队列不为空
pthread_cond_signal(¬_empty_);
// 释放锁
pthread_mutex_unlock(&mtx_);
}
void pop(T* out=nullptr)
{
//先申请互斥锁
pthread_mutex_lock(&mtx_);
// 加锁检测条件
while(this->is_empty())
{
pthread_cond_wait(¬_empty_,&mtx_);
}
// 条件满足并已加锁 , 消费一个数据
if(out)
*out=bq_.front();// 取出队列的一个数据
bq_.pop();
// 通知生产者可以继续生产
pthread_cond_signal(¬_full_);
// 解锁
pthread_mutex_unlock(&mtx_);
}
private:
std::queue<T>bq_;
pthread_mutex_t mtx_;
pthread_cond_t not_full_;
pthread_cond_t not_empty_;
size_type capacity_;
//bool done = false;
};