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

📄 ysqueue.h

📁 VisualC++通信编程工程实例精解 Chapter 2 Example 1 MSCOMM控件编程实例 Example 2 基于Windows API的虚拟终端实现 Example 3
💻 H
字号:
// Queue.h: interface for the CQueue class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_QUEUE_H__ECADBF81_B282_11D5_971D_0050BADA81C3__INCLUDED_)
#define AFX_QUEUE_H__ECADBF81_B282_11D5_971D_0050BADA81C3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/****************************************************************
名称:				模板线程同步队列类
作者:				广州暨南大学97计算机 姚舜
EMAIL:				ycatx@ycatx.net
创建时间:			2003.5.16
最近修改时间:		2003.5.16
功能:				循环队列操作,支持超时功能
使用:				先Init(nSize),然后才可以进行Put(),Get()操作,循环队列操作的封装
说明:				支持多线程
等级:				☆
****************************************************************/
template<typename ElementT>
class CYsQueue   
{
public:
	UINT GetLastError()
	{
		return m_uLastError;
	}

	int m_nSize;//队列长度


	int GetCount()//取得当前队列的总数
	{
		m_uLastError=0;
		return m_iCount;
	}

	CYsQueue(UINT uSize)
	{
		m_iCount=0;
		m_pQueue=NULL;
		m_nRear=m_nFront=0;
		m_handle[0]=NULL;
		m_handle[1]=NULL;
		m_nSize=0;
		m_uLastError=0;
		Init(uSize);
	}

	virtual ~CYsQueue()
	{
		if(m_handle[0]) CloseHandle(m_handle[0]);
		if(m_handle[1]) CloseHandle(m_handle[1]);
		delete m_pQueue;
	}

	BOOL Clear()//清除列队
	{
		m_uLastError=0;
		//非暴力手法
		//等待互斥对象
		DWORD dw=WaitForSingleObject(m_handle[0],INFINITE);

		if(dw!=WAIT_OBJECT_0)
		{
			TRACE("Clear Function 出现不应该出现的错误%d\n",
				GetLastError());
			m_uLastError=1;
			return FALSE;
		}
		TRACE("clear queue\n");
		CloseHandle(m_handle[1]);//关掉信标

		m_handle[1]=CreateSemaphore(NULL,0,m_nSize,NULL);//创建信标

		if(!m_handle[1])
		{
			TRACE("初始化信标失败!\n");
			m_uLastError=9;
			return FALSE;
		}
		m_nRear=m_nFront=0;
		ReleaseMutex(m_handle[0]);
		return TRUE;
	}


	BOOL Put(ElementT* pElement,int iCount=1)//插入队列
	{
		m_uLastError=0;
		ASSERT(m_nSize);
		//等待互斥对象
		DWORD dw=WaitForSingleObject(m_handle[0],INFINITE);
		
		//超时,或出错//应该不会出现这种情况
		if(dw==WAIT_FAILED)
		{
			m_uLastError=6;
			TRACE("put function 出现不应该出现的错误:%d\n",
				GetLastError());
		}
		
		if(dw!=WAIT_OBJECT_0)
		{
			m_uLastError=1;
			TRACE("put function 出现不应该出现的错误:%d\n",
				GetLastError());
			return FALSE;
		}

		BOOL fOk;
		for(int i=0;i<iCount;i++)
		{
			fOk=FALSE;
			//递增信标
			fOk=ReleaseSemaphore(m_handle[1],1,NULL);

			if(!fOk)	//队列已经满,应该不会出现
			{
				CString s;
				m_uLastError=8;
				TRACE(s);
				ReleaseMutex(m_handle[0]);
				return FALSE;
			}
			m_iCount++;

			memmove(&m_pQueue[m_nRear],pElement+i,sizeof(ElementT));
			m_nRear=(m_nRear+1)%m_nSize;
		}
		ReleaseMutex(m_handle[0]);
		return TRUE;
	}

	BOOL Get(ElementT* pElement,DWORD dwTimeOut=INFINITE,int iCount=1)//从对队列中取出一个元素
	{
		ASSERT(m_nSize);
		DWORD dw;
		iCount=1;//目前技术只能为1
		for(int i=0;i<iCount;i++)
		{
			//等侍队列里有数据
			dw=WaitForMultipleObjects(2,m_handle,TRUE,dwTimeOut);

			switch(dw)
			{
			case WAIT_OBJECT_0:
				m_iCount--;
				break;

			case WAIT_TIMEOUT:
				//TRACE("CQueue->Get wait time out\n");
				ReleaseMutex(m_handle[0]);
				return FALSE;

			default:
				TRACE("get function 出现不应该出现的错误:%d\n",
					GetLastError());
				return FALSE;
			}
			memmove(pElement+i,&m_pQueue[m_nFront],sizeof(pElement));
			m_nFront=(m_nFront+1)%m_nSize;
			ReleaseMutex(m_handle[0]);
		}
		return TRUE;
	}
private:
	UINT m_uLastError;
	int m_iCount;
	HANDLE m_handle[2];//m_handle[0]为互斥句柄,m_handle[1]为信标句柄
	int m_nFront;//队列头
	int m_nRear;//队列尾
	ElementT * m_pQueue;//对列数组

	BOOL Init(int nSize)//初始化队列
	{
		m_uLastError=0;
		m_handle[0]=CreateMutex(NULL,FALSE,NULL);//创建互斥句柄
		m_handle[1]=CreateSemaphore(NULL,0,nSize,NULL);//创建信标

		if(!m_handle[0])
		{
			ASSERT(0);
			m_uLastError=9;
			TRACE("初始化互斥失败!\n");
			return FALSE;
		}
		if(!m_handle[1])
		{
			ASSERT(0);
			m_uLastError=9;
			TRACE("初始化信标失败!\n");
			return FALSE;
		}
		m_nSize=nSize;
		m_pQueue=new ElementT[nSize];
		
		if(m_pQueue==NULL)
		{
			ASSERT(0);
			m_uLastError=8;
			TRACE("生成m_pQueue空间不够\n");
		}
		VERIFY(m_pQueue);
		return TRUE;
	}
};
#endif // !defined(AFX_QUEUE_H__ECADBF81_B282_11D5_971D_0050BADA81C3__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -