⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 equeue.h

📁 这是书上的代码
💻 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 + -