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

📄 packetquemanager.h

📁 一个实现可以在进程间或者线程间通信的高效环形队列类
💻 H
字号:
// PacketQueManager.h: interface for the CPacketQueManager class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PACKETQUEMANAGER_H__3286F4CE_2021_41E5_B4D4_F0DB5C155817__INCLUDED_)
#define AFX_PACKETQUEMANAGER_H__3286F4CE_2021_41E5_B4D4_F0DB5C155817__INCLUDED_

#include "ace/Basic_Types.h"
//这个是实现包队列管理器
//在实际的应用中,一个线程或者进程向一个队列的末尾写数据
//另外一个线程或者进程从队列头都数据。
//如何快速的同步这一个读者(Reader)和写者(Writer)是这个类的实现目的

//千万注意:这个类只能用于一个读者和一个写者的情况。
//对于任何读者>2或者写者>2都是错误的。


class CPacketQueManager 
{
public:
	enum{
		READER = 1,WRITER = 2,READWRITER = READER|WRITER,
	};

private:
	enum{
		BUFFER_LOCK_FALG = 0,
		BUFFER_FULL_FLAG = 1,
			BUFFER_NOT_FULL_FLAG = 2,
	};
private:
	//共享缓冲区头部结构
	typedef struct
	{
		ACE_UINT32 dwState;     //0;不准往缓冲区写数据
		ACE_UINT32 dwSizeBuffer;//只包括存放数据帧部分的大小,不包括SHARE_BUFFER_HEADER本身
		ACE_UINT32 dwReadPos;
		ACE_UINT32 dwWritePos;
	}SHARE_BUFFER_HEADER;
	
	//为每一个包定义一个包头
	typedef struct{

		ACE_UINT32 dwOrgSize;//每一个包的原始大小
		
	}PACKET_HEADER;

	
public:
	CPacketQueManager();
	virtual ~CPacketQueManager();

public:	
	
	//当nUserType存在Writer时,dwSizeBuffer必须不为0。
	//如果用户已经开辟了缓冲区,通过pBuffer传进来,如果pBuffer=0,由内部创建和删除

	//当nUserType不存在Writer时,pBuffer是Writer的Create的返回值,dwSizeBuffer无效。
	//如果成功,返回缓冲区的地址
	//dwSizeBuffer,缓冲区大小,以字节为单位(dwSizeBuffer>=100)
	void * Create(ACE_UINT32 nUserType, void * pBuffer, ACE_UINT32 dwSizeBuffer );

	inline void * CreateAsWriter(void * pBuffer, ACE_UINT32 dwSizeBuffer)
	{
		return Create( WRITER, pBuffer, dwSizeBuffer );
	}
	inline void * CreateAsReader(void * pBuffer)
	{
		return Create( READER, pBuffer, 0 );
		
	}
	inline void * CreateAsWriteReader(void * pBuffer, ACE_UINT32 dwSizeBuffer)
	{
		return Create(READWRITER, pBuffer, dwSizeBuffer);
	}
	//释放资源,准备退出
	//必须保证在停止任何读,写的条件下调用
	void Destroy();
	
	//只有在m_dwUserType&WRITERER != 0时才能调用
	bool  WritePacket(const void * packet,ACE_UINT32 dwPacketSize);

	//读包,返回包的大小。在参数ppPakcet返回包的指针
	//返回值:0--没有取到数据信息
	//        数据包长度--取到当前包信息,如果len为0,该包是无效的
	//只有在m_dwUserType&READER != 0时才能调用
	ACE_UINT32 ReadPacket(void** ppPakcet);

	//用户只有在ReadPacket返回值>0时才能调用这个函数。
	void  SkipToNextPacket();

	//清楚所有数据
	//必须保证在停止任何读,写的条件下调用。
	//调用函数返回之后,才能再次读写数据
	inline void  ClearQueue()
	{
		if( m_pShareBufferHeader )
		{
			m_pShareBufferHeader->dwReadPos = 0;
			m_pShareBufferHeader->dwWritePos = 0;			
		}
	}
	
	//只有在m_dwUserType&WRITERER != 0时才能调用
	//ReserveBufferWritePacket和WriteReservedBuffer必须成对使用
	//如果ReserveBufferWritePacket没有返回空,那么用户在添完数据后,必须调用WriteReservedBuffer
	//如果用户调用WriteReservedBufferUseRealSize,必须保证dwRealPacketSize<dwPacketSize.

	//而且两个函数之间不允许调用ReserveBufferWritePacket或者WritePacket。
	BYTE *  ReserveBufferWritePacket(ACE_UINT32 dwPacketSize);
	void	WriteReservedBuffer();
	void	WriteReservedBufferUseRealSize(ACE_UINT32 dwRealPacketSize);
	
	static ACE_UINT32 GetFourByteAlign(ACE_UINT32 dwData)
	{
		if (dwData & 0x03) dwData = (dwData & (~0x03)) + 4;
		return dwData;		
	}
	
private:
	CPacketQueManager(const CPacketQueManager& pqm);
	const CPacketQueManager& operator = (const CPacketQueManager& pqm);

private:
	ACE_UINT32					m_dwUserType;

	SHARE_BUFFER_HEADER *	m_pShareBufferHeader;
	BYTE *					m_pInfoBuffer;
	ACE_UINT32					m_dwEndPos;

	ACE_UINT32					m_dwLastPackLen;
	
	//是否由内部来创建数据
	bool					   m_bCreateBuffer;

	ACE_UINT32					m_dwNowWritePos;

};

#endif // !defined(AFX_PACKETQUEMANAGER_H__3286F4CE_2021_41E5_B4D4_F0DB5C155817__INCLUDED_)


⌨️ 快捷键说明

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