demo源码 阻塞队列部分¶
queue.h //主要是对queue加了几把pv锁,对push和pop分别做了阻塞和非阻塞的封装,主要内容见注释,不复杂,此处不赘述。
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include <queue>
namespace Queue
{
template<typename TYPE> class Queue
{
private:
typedef std::queue<TYPE> queue_t;
queue_t m_queue;
pthread_mutex_t m_queuemutex;//互斥锁
pthread_cond_t m_queuefill;
bool m_waitqueuefill;//等待队列有数据可pop的条件变量
pthread_cond_t m_queuefree;
bool m_waitqueuefree;//等待队列有空位可push的条件变量
const size_t m_queuelen;//队列长度
public:
Queue(size_t queuelen): m_waitqueuefill(false), m_queuelen(queuelen){ };
~Queue(){};
// 返回队列大小
size_t size()
{
return (size_t)m_queue.size();
};
//清空队列
int clear()
{
pthread_mutex_lock(&m_queuemutex);
while(!m_queue.empty());
m_queue.pop();
pthread_mutex_unlock(&m_queuemutex);
return 0;
};
// 非阻塞方式pop队列中数据
int pop_nonblock(TYPE &out)
{
pthread_mutex_lock(&m_queuemutex);
if(m_queue.size() == 0)//队列空
{
pthread_mutex_unlock(&m_queuemutex);
return -1;
}
out = m_queue.front();
m_queue.pop();
if(m_waitqueuefree){
pthread_cond_signal(&m_queuefree);//通知阻塞push
m_waitqueuefree = false;
}
pthread_mutex_unlock(&m_queuemutex);
return 0;
};
// 阻塞式pop队列中数据
int pop(TYPE &out)
{
pthread_mutex_lock(&m_queuemutex);
while(m_queue.size() == 0){
m_waitqueuefill = true;
pthread_cond_wait(&m_queuefill, &m_queuemutex);// 队列空,令线程阻塞等待直至有数据
}
out = m_queue.front();
m_queue.pop();
if(m_waitqueuefree){
pthread_cond_signal(&m_queuefree);//通知阻塞push
m_waitqueuefree = false;
}
pthread_mutex_unlock(&m_queuemutex);
return 0;
};
// 非阻塞式push数据进入队列
int push_nonblock(TYPE & in)
{
pthread_mutex_lock(&m_queuemutex);
if(m_queue.size() == m_queuelen)//队列满
{
pthread_mutex_unlock(&m_queuemutex);
return -1;
}
m_queue.push(in);
if(m_waitqueuefill){
pthread_cond_signal(&m_queuefill);//通知阻塞pop
m_waitqueuefill = false;
}
pthread_mutex_unlock(&m_queuemutex);
return 0;
};
//阻塞式push数据进入队列
int push(TYPE & in)
{
pthread_mutex_lock(&m_queuemutex);
while(m_queue.size() == m_queuelen){
m_waitqueuefree = true;
pthread_cond_wait(&m_queuefree, &m_queuemutex);// 队列满,令线程阻塞等待直至可push数据
}
m_queue.push(in);
if(m_waitqueuefill){
pthread_cond_signal(&m_queuefill);//通知阻塞pop
m_waitqueuefill = false;
}
pthread_mutex_unlock(&m_queuemutex);
return 0;
};
};
}
#endif