📄 equeue.h
字号:
/////////////////////////////////////////////////////////////////////////////
//
//
// Copyright Declaration
//
// This source code is designed by Huang Yifeng(China).
// You can use the source code, but please reserve the Copyright
// Declaration in this code. Or you should be ready to be punished
// by the related law.
//
// Huang Yifeng
// edward_hyf@sohu.com
// 2003.7.8
//////////////////////////////////////////////////////////////////////////////
#ifndef __CEXCLUSION_CIRCLE_QUEUE__
#define __CEXCLUSION_CIRCLE_QUEUE__
#include "definition.h"
template <class UNIT_TYPE>
class CExclusionCircleQueue
{
public:
CExclusionCircleQueue()
{
queue = NULL;
}
~CExclusionCircleQueue()
{
Close();
}
bool Create(int max_queue_length)
{
MaxQueueLength = max_queue_length;
header = 0;
tailer = 0;
GetSuspended = 0;
PutSuspended = 0;
semEmptySpaces.Create(0,MaxQueueLength);
semValidDatas.Create(0,MaxQueueLength);
GetInsideOperations = 0;
PutInsideOperations = 0;
queue = new UNIT_TYPE[MaxQueueLength+1];
ASSERT(queue!=NULL);
if(queue==NULL)
return false;
else
return true;
}
void Close()
{
header = 0;
tailer = 0;
semEmptySpaces.Close();
semValidDatas.Close();
if(queue)
{
delete []queue;
queue = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// blocking version
/////////////////////////////////////////////////////////////////////////////
bool GetHeader(UNIT_TYPE &out, DWORD timeout=INFINITE)
{
rwlock.WriterAcquire();
if((LengthEx()==0)||(GetInsideOperations!=0))
{
GetInsideOperations++;
GetSuspended++;
rwlock.WriterRelease();
if(!semValidDatas.Acquire(timeout))
{
return false; // timeout
}
rwlock.WriterAcquire();
GetInsideOperations--;
}
out = queue[header];
header = (header+1)%(MaxQueueLength+1);
printf("Get %d \n", out);
if(PutSuspended>0)
{
PutSuspended--;
semEmptySpaces.Release();
}
rwlock.WriterRelease();
return true;
}
bool PutTailer(UNIT_TYPE in, DWORD timeout=INFINITE)
{
long temp;
rwlock.WriterAcquire();
if(((temp=LengthEx())==MaxQueueLength)||(PutInsideOperations!=0))
{
PutInsideOperations++;
PutSuspended++;
rwlock.WriterRelease();
if(!semEmptySpaces.Acquire(timeout))
{
return false; // timeout
}
rwlock.WriterAcquire();
PutInsideOperations--;
}
queue[tailer] = in;
tailer = (tailer+1)%(MaxQueueLength+1);
printf("Put %d \n", in);
if(GetSuspended>0)
{
GetSuspended--;
semValidDatas.Release();
}
rwlock.WriterRelease();
return true;
}
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// unblocking version
/////////////////////////////////////////////////////////////////////////////
bool GetHeaderEx(UNIT_TYPE &out)
{
rwlock.WriterAcquire();
if(IsEmpty()||(GetInsideOperations!=0))
{
rwlock.WriterRelease();
return false;
}
out = queue[header];
header = (header+1)%(MaxQueueLength+1);
printf("Get %d \n", out);
if(PutSuspended>0)
{
PutSuspended--;
semEmptySpaces.Release();
}
rwlock.WriterRelease();
return true;
}
bool PutTailerEx(UNIT_TYPE in)
{
rwlock.WriterAcquire();
if(IsFull()||(PutInsideOperations!=0))
{
rwlock.WriterRelease();
return false;
}
queue[tailer] = in;
tailer = (tailer+1)%(MaxQueueLength+1);
printf("Put %d \n", in);
if(GetSuspended>0)
{
GetSuspended--;
semValidDatas.Release();
}
rwlock.WriterRelease();
return true;
}
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
// Attention: Empty() is not a safety function, you'd better not call it.
// It can be only called in the following test program.
void Empty()
{
rwlock.WriterAcquire();
header = 0;
tailer = 0;
rwlock.WriterRelease();
}
int Length()
{
rwlock.ReaderAcquire();
int result = (tailer-header+(MaxQueueLength+1))%(MaxQueueLength+1);
rwlock.ReaderRelease();
return result;
}
private:
int LengthEx()
{
int result = (tailer-header+(MaxQueueLength+1))%(MaxQueueLength+1);
return result;
}
bool IsFull()
{
bool result = ((tailer+1)%(MaxQueueLength+1) == header);
return result;
}
bool IsEmpty()
{
bool result = (header == tailer);
return result;
}
private:
int MaxQueueLength;
int header, tailer;
class CRWLock rwlock;
UNIT_TYPE * queue;
CSemaphoreEx semEmptySpaces;
CSemaphoreEx semValidDatas;
int GetSuspended;
int PutSuspended;
int GetInsideOperations;
int PutInsideOperations;
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -