📄 basequeue.h
字号:
#ifndef __BaseQueue_H__
#define __BaseQueue_H__
#include "ResourceBase.h"
const int constDEFAULTQUEUESIZE = 512 ;
template <class T> class BaseQueue
{
T **data;
int size;
T **head;
T **tail;
T **dataend;
CTSemaphore pOccupiedSema;
CTCriticalSection m_lock;
public:
BaseQueue(int aSize = constDEFAULTQUEUESIZE, int isMulti = 1);
//Constructor, aSize=buffer size, isMulti=true means there are mutliple producer/consumer.
~BaseQueue();
void Put(T &newData);
//Put a new data into queue, if queue is occupied that block until not occupied.
void Get(T &buf);
//Get a data from queue, if queue is empty that block until not empty.
int Remove();
void RemoveAll() ;
int TryPut(T &newData);
//Put a new data into queue, if queue is occupied that return -1 else return 0.
int TryGet(T &buf);
//Get a data from queue, if queue is empty that return -1 else return 0.
// int TryRemove();
int PutHead(T &newData);
//Put a new data into queue head, if queue is occupied that return -1 else return 0.
int TryPutHead(T &newData);
int Peek(T &buf);
int GetCount();
int IsEmpty() ;
int IsOccupied() ;
private:
inline int InnerGetCount();
inline int InnerPut(T &newData);
inline void InnerGet(T &buf);
};
// Queue:
// +----+----+----+----+----+----+----+----+----+
// |T* |T* | | | | | | | |
// +----+----+----+----+----+----+----+----+----+
// ^ ^ ^ ^
// data head tail dataend
//
// <---- count --->
// <---------------- size ----------------->
// <-------------- buffer size ----------------->
//
// IsEmpty: if head=tail
// IsOccupied: if tail=head-1
//////////////////////////////////////////////////////
//Purpose : 构造函数
//Input Paras :
// aSize 指定队列的大小
// isMulti 已经废除,全部都是多线程的处理方式,
// 不是多线程的话,请使用std::queue
//Output Paras : 无
//Return Value : 无
//Relations : 无
///////////////////////////////////////////////////////
template <class T>
BaseQueue< T >::BaseQueue(int aSize, int /*isMulti*/) :
#ifdef WIN32
pOccupiedSema(0,aSize)
#else
pOccupiedSema(0)
#endif
{
size = aSize>0?aSize:1;
typedef T* TP;
data = new TP [size+1];
assert(data);
for(int i=0; i<=size; i++)
data[i]=0;
tail = head = data;
dataend = data+size+1;
}
//////////////////////////////////////////////////////
//Purpose : 析构函数,释放全部队列资源
//Input Paras : 无
//Output Paras : 无
//Return Value : 无
//Relations : 无
///////////////////////////////////////////////////////
template <class T>
BaseQueue< T >::~BaseQueue()
{
for(int i = 0; i<=size; i++)
{
delete data[i];
data[i] = 0 ;
}
delete [] data;
}
template <class T>
int BaseQueue< T >::GetCount()
{
int count=0;
m_lock.Lock();
count=InnerGetCount();
m_lock.Unlock();
return count;
}
template <class T>
int BaseQueue< T >::IsEmpty()
{
int ret=0;
m_lock.Lock();
ret = (InnerGetCount() == 0 );
m_lock.Unlock();
return ret ;
}
template <class T>
int BaseQueue< T >::IsOccupied()
{
int ret=0;
m_lock.Lock();
ret = (InnerGetCount() == size );
m_lock.Unlock();
return ret ;
}
//////////////////////////////////////////////////////
//Purpose : put一个元素到队列(末尾)
//Input Paras :
// newData 要放到队列中的元素
//Output Paras : 无
//Return Value : 无
//Relations : newData的类必须支持复制
//Note : 此函数在队列满的情况下,不执行put动作,参考TryPut函数
///////////////////////////////////////////////////////
template <class T>
void BaseQueue< T >::Put(T &newData)
{
int ret=-1;
m_lock.Lock();
if( InnerGetCount() < size )
{
ret = InnerPut(newData);
pOccupiedSema.Post();
}
m_lock.Unlock();
return ;
}
//////////////////////////////////////////////////////
//Purpose : 尝试put一个元素到队列(尾部),
// 如果队列已经满,则返回-1,否则返回0
//Input Paras :
// newData 要put的元素
//Output Paras :
// -1 队列满
// 0 成功
//Return Value :
//Relations : newData的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::TryPut(T &newData)
{
int ret=-1;
m_lock.Lock();
if( InnerGetCount() < size )
{
ret = InnerPut(newData);
pOccupiedSema.Post();
}
m_lock.Unlock();
return ret;
}
//////////////////////////////////////////////////////
//Purpose : put一个元素到对列头
//Input Paras :
// newData 要放到队列中的元素
//Output Paras : 无
//Return Value : 无
//Relations : newData的类必须支持复制
//Note : 此函数在队列满的情况下,不执行put动作,参考TryPutHead函数
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::PutHead(T &newData)
{
int ret=-1;
m_lock.Lock();
if( InnerGetCount() < size )
{
T *tmpdata = new T ;
if( tmpdata )
{
*tmpdata = newData;
if( head == data )
head = data+size ;
else
head -- ;
*head = tmpdata;
pOccupiedSema.Post();
ret = 0 ;
}
}
m_lock.Unlock();
return ret ;
}
//////////////////////////////////////////////////////
//Purpose : 尝试put一个元素到队列头,如果队列已经满,则返回-1,否则返回0
//Input Paras :
// newData 要put的元素
//Output Paras :
// -1 队列满
// 0 成功
//Return Value :
//Relations : newData的类必须支持复制
///////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::TryPutHead(T &newData)
{
int ret=-1;
m_lock.Lock();
if( InnerGetCount() < size )
{
T *tmpdata = new T ;
if( tmpdata )
{
*tmpdata = newData;
if( head == data )
head = data+size ;
else
head -- ;
*head = tmpdata;
pOccupiedSema.Post();
ret = 0 ;
}
}
m_lock.Unlock();
return ret ;
}
//////////////////////////////////////////////////////
//Purpose : 取得一个队列的当前元素,如果队列是空的话,那么一直等待
//Input Paras : 无
//Output Paras :
// buf 返回取得的元素
//Return Value : 无
//Relations : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
void BaseQueue< T >::Get(T &buf)
{
pOccupiedSema.Wait();
m_lock.Lock();
InnerGet(buf);
m_lock.Unlock();
}
//////////////////////////////////////////////////////
//Purpose : 尝试取得一个队列的当前元素
//Input Paras : 无
//Output Paras :
// buf 返回取得的元素
//Return Value :
// -1 表示当前队列是空的
// 0 成功
//Relations : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::TryGet(T &buf)
{
/* if( IsEmpty() )
return -1;
pOccupiedSema.Wait();
m_lock.Lock();
InnerGet(buf);
m_lock.Unlock();
return 0 ;
*/
int ret=-1;
m_lock.Lock();
if( InnerGetCount() > 0 )
{
pOccupiedSema.Wait();
InnerGet(buf);
ret = 0 ;
}
m_lock.Unlock();
return ret;
}
//////////////////////////////////////////////////////
//Purpose : 查看一个队列的当前元素
//Input Paras : 无
//Output Paras :
// buf 返回取得的元素
//Return Value :
// -1 表示当前队列是空的
// 0 成功
//Relations : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::Peek(T & buf)
{
int ret=-1;
m_lock.Lock();
if( InnerGetCount() )
{
buf = **head;
ret = 0 ;
}
m_lock.Unlock();
return ret;
}
//////////////////////////////////////////////////////
//Purpose : 删除当前队列头元素
//Input Paras : 无
//Output Paras : 无
//Return Value :
// -1 队列是空的
// 0 删除成功
//Relations : 无
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::Remove()
{
T tmp;
TryGet( tmp ) ;
return 0 ;
}
template <class T>
void BaseQueue< T >::RemoveAll()
{
T tmp;
for(;;)
{
if( TryGet(tmp) != 0 )
break;
}
}
///////////private/////////////////////////
template <class T>
int BaseQueue< T >::InnerGetCount()
{
if (tail>=head)
return ( int )(tail-head);
else
return ( int )(size+1-(head-tail));
}
template <class T>
inline void BaseQueue< T >::InnerGet(T &buf)
{
buf = **head; // operator =
T* prev = *head;
delete prev;
*head = NULL;
head++;
if (head>=dataend)
head = data;
}
template <class T>
inline int BaseQueue< T >::InnerPut(T &newData)
{
T *tmpdata = new T;
if( tmpdata )
{
*tmpdata = newData ;
*tail = tmpdata ;
tail++;
if (tail>=dataend)
tail = data;
return 0 ;
}
return -1;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -