共享内存,实现消息队列,提供多进程通信

haoruixiang 2014-05-13 11:23:04
#define  MMSGQ_FLAG "MMSG"
#define MAX_MSG_SIZE (1024*1024*16) //最大消息长度为4M
#define MSGQ_OFFSET 10000

#include "hrx_thread.h"
#include "Memery.h"
/*
MMSGBlock Msg的总块数 每块512个字节 512M = 512*1024 块 50万块
MMSGQ 消息队列 消息队列的块数,起始块,末端块,消息队列的起始,消息队列的数量
*/
#define MAX_MSGQ_CNT 256 //消息队列数量
#define MAX_BLOCK_SIZE 1024 //每块大小

typedef struct
{
void * m_NextBlock; //Next block, 0 means the last block
unsigned int m_MsgFlag; //MsgFlag编号
unsigned int m_InTime; //Insert time
unsigned int m_MsgLength; //Length of the message
unsigned int m_DataLength; //The data length in this block
void * m_Data; //message body
}MMSG;

typedef struct
{
MMSG * m_FirstBlock; //第一个块
MMSG * m_LastBlock; //最后一个块
unsigned int m_BlockCount; //块的数量
unsigned int m_freeCount; //空闲块的数量
}MsgBlockInfo;

typedef struct
{
LOCK_INFOS m_Lock;
char m_Name[128];
unsigned int m_Status;
unsigned int m_QID; //每个消息队列的ID,在MsgQs[MAX_MSGQ_CNT]中的槽位
unsigned int m_CreateTime; //消息队列创建的时间
MsgBlockInfo m_Msginfo; //消息存储容器
MMSG * m_ReadCurrent; //当前读取的消息位置
MMSG * m_WriteCurrent; //当前写入的消息位置
unsigned int m_MsgCount; //本消息队列的中消息的条数
unsigned int m_MsgQSize; //消息队列大小
}MMSGQ;

typedef struct
{
LOCK_INFOS m_Lock;
char m_Flags[4]; //"MMSG"
char m_Name[128];
unsigned int m_Version;

unsigned int m_SysTime;
unsigned int m_TimeTicks;
unsigned int m_CreateTime;
MsgBlockInfo m_DBBlock;
MMSGQ m_MsgQs[MAX_MSGQ_CNT]; //消息队列区,最多可以创建MAX_MSGQ_CNT个消息队列
}MMSGQ_DCB; //MessageQ device control block


#define ERROR_MSGQ_NO1 -100 //内存没有建立或者容量不够
#define ERROR_MSGQ_NO2 -101 //初始化内存锁失败
#define ERROR_MSGQ_NO3 -102 //初始化消息队列锁失败
#define ERROR_MSGQ_NO4 -103 //枷锁失败
#define ERROR_MSGQ_NO5 -104 //消息队列已用完,初始化失败
#define ERROR_MSGQ_NO6 -105 //查找内容不在范围之内,或者传入的参数错误
#define ERROR_MSGQ_NO7 -106 //查找的内容已经作废
#define ERROR_MSGQ_NO8 -107 //消息队列味初始化
#define ERROR_MSGQ_NO9 -108 //消息队列已满
#define ERROR_MSGQ_N10 -109 //接收的容量不够
#define ERROR_MSGQ_N11 -110 //严重错误,数据已经混乱

static char* ERRORINFO[] = {
"内存没有建立或者容量不够",
"初始化内存锁失败",
"初始化消息队列锁失败",
"枷锁失败",
"消息队列已用完,初始化失败",
"查找内容不在范围之内,或者传入的参数错误",
"查找的内容已经作废",
"消息队列味初始化",
"消息队列已满",
"接收的容量不够",
"严重错误,数据已经混乱"
};

...全文
434 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
版主大哥 2014-05-13
  • 打赏
  • 举报
回复
Memery.h 写错了吧 Memory
haoruixiang 2014-05-13
  • 打赏
  • 举报
回复

[code=c]

class HMMsgQ : public ShareMemery
{
public:
	HMMsgQ(){};
	~HMMsgQ(){};
	//初始化MsgQ
	int InitMsgQ()
	{
		char * sptr = (char*)GetPtr();
		int  size = GetSize();
		if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
		{
			return ERROR_MSGQ_NO1;   //内存没有建立或者容量不够
		}
#ifdef HRX_LINUX
		pthread_mutexattr_t mutexattr;
		pthread_mutexattr_init(&mutexattr);
		pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);
#endif
		MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
		char * data = sptr;
		data += sizeof(MMSGQ_DCB);
		data += MAX_BLOCK_SIZE;
		int datalen = size - sizeof(MMSGQ_DCB) - MAX_BLOCK_SIZE;
		int bcnt = datalen/(MAX_BLOCK_SIZE+sizeof(MMSG));
#ifdef  HRX_NO_MEMERY
		InitializeCriticalSection(&(pp->m_Lock.mutex));
#endif
		
#ifdef  HRX_LINUX
		if( pthread_mutex_init( &(pp->m_Lock.mutex), &mutexattr ) < 0 )
		{
			return ERROR_MSGQ_NO2;  //初始化锁失败
		}
#endif
		pp->m_DBBlock.m_BlockCount = bcnt;
		pp->m_DBBlock.m_freeCount = bcnt;
		pp->m_DBBlock.m_FirstBlock = (MMSG*)data;
		pp->m_DBBlock.m_LastBlock = (MMSG*)data;
		data += sizeof(MMSG);
		pp->m_DBBlock.m_FirstBlock->m_DataLength = 0;
		pp->m_DBBlock.m_FirstBlock->m_MsgFlag = 0;
		pp->m_DBBlock.m_FirstBlock->m_MsgLength = MAX_BLOCK_SIZE;
		pp->m_DBBlock.m_FirstBlock->m_NextBlock = pp->m_DBBlock.m_FirstBlock;
		pp->m_DBBlock.m_FirstBlock->m_InTime = 0;
		pp->m_DBBlock.m_FirstBlock->m_Data = (void*)data;
		data += MAX_BLOCK_SIZE;
		MMSG * prev = pp->m_DBBlock.m_LastBlock;
		for( int i = 1; i < bcnt; i++ )
		{
			MMSG * fp = (MMSG*)data;
			data += sizeof(MMSG);
			fp->m_DataLength = 0;
			fp->m_MsgFlag = i;
			fp->m_MsgLength = MAX_BLOCK_SIZE;
			fp->m_NextBlock = pp->m_DBBlock.m_FirstBlock;
			fp->m_InTime = 0;
			fp->m_Data = (void*)data;
			data += MAX_BLOCK_SIZE;
			prev->m_NextBlock = (void*)fp;
			prev = fp;
			pp->m_DBBlock.m_LastBlock = fp;
		}
		for( int i = 0; i < MAX_MSGQ_CNT; i++ )
		{
			memset(pp->m_MsgQs[i].m_Name,0,sizeof(pp->m_MsgQs[i].m_Name));
			pp->m_MsgQs[i].m_CreateTime = 0;
			pp->m_MsgQs[i].m_Lock;
			pp->m_MsgQs[i].m_MsgCount = 0;
			pp->m_MsgQs[i].m_MsgQSize = 0;
			pp->m_MsgQs[i].m_QID = i;
			pp->m_MsgQs[i].m_Status = 0;
			pp->m_MsgQs[i].m_Msginfo.m_BlockCount = 0;
			pp->m_MsgQs[i].m_Msginfo.m_FirstBlock = NULL;
			pp->m_MsgQs[i].m_Msginfo.m_freeCount = 0;
			pp->m_MsgQs[i].m_Msginfo.m_LastBlock = NULL;
			pp->m_MsgQs[i].m_ReadCurrent = NULL;
			pp->m_MsgQs[i].m_WriteCurrent = NULL;
#ifdef  HRX_NO_MEMERY
			InitializeCriticalSection(&(pp->m_MsgQs[i].m_Lock.mutex));
#endif
		
#ifdef  HRX_LINUX
			if( pthread_mutex_init( &(pp->m_MsgQs[i].m_Lock.mutex), &mutexattr ) < 0 )
			{
				return ERROR_MSGQ_NO3; //初始化锁失败
			}
#endif
		}
		return 0;
	};
	int InitMsgQ( char* name,int msgcnt )
	{
		char * sptr = (char*)GetPtr();
		int  size = GetSize();
		if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
		{
			return ERROR_MSGQ_NO1;
		}
		MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef  HRX_MEMERY
		HrxTLockx_Event mksk( GetEventHandle(),200);
		if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
		FUNCTION_LOCK slock(&(pp->m_Lock));
#endif
		for( int i = 0; i < MAX_MSGQ_CNT; i++ )
		{
			if( pp->m_MsgQs[i].m_Status == 0 )
			{
				pp->m_MsgQs[i].m_CreateTime = time(0);
				strcpy(pp->m_MsgQs[i].m_Name,name);
				pp->m_MsgQs[i].m_MsgCount = 0;
				pp->m_MsgQs[i].m_MsgQSize = msgcnt;
				pp->m_MsgQs[i].m_QID = i;
				pp->m_MsgQs[i].m_Status = 1;
				pp->m_MsgQs[i].m_Msginfo.m_BlockCount = msgcnt;
				pp->m_MsgQs[i].m_Msginfo.m_freeCount = msgcnt;
				pp->m_MsgQs[i].m_Status = 1;
				for(int j = 0; j < msgcnt; j++ )
				{
					MMSG * vp = NULL;
					if( GetMMSG(&(pp->m_DBBlock),vp) < 0 ) break;
					SetMMSG(&(pp->m_MsgQs[i].m_Msginfo),vp);
				}
				pp->m_MsgQs[i].m_ReadCurrent = pp->m_MsgQs[i].m_Msginfo.m_FirstBlock;
				pp->m_MsgQs[i].m_WriteCurrent = pp->m_MsgQs[i].m_Msginfo.m_FirstBlock;
				return i;
			}		
		}
		return ERROR_MSGQ_NO5;
	};
	int GetMMSG( MsgBlockInfo* pp,MMSG *& vp )
	{
		if( pp->m_BlockCount <= 0 ) return -1;
		if( pp->m_freeCount <= 0 ) return -1;
		vp = pp->m_FirstBlock;
		MMSG * sp = (MMSG *)(pp->m_FirstBlock->m_NextBlock);
		pp->m_FirstBlock = sp;
		vp->m_NextBlock = NULL;
		pp->m_freeCount -- ;
		if( pp->m_freeCount == 0 )
		{
			pp->m_FirstBlock = NULL;
			pp->m_LastBlock = NULL;
		}
		else
		{
			pp->m_LastBlock->m_NextBlock = pp->m_FirstBlock;
		}
		return 0;
	};
	int SetMMSG( MsgBlockInfo* pp,MMSG * vp )
	{
		if( pp->m_BlockCount == 0 )
		{
			pp->m_FirstBlock = vp;
			pp->m_LastBlock = vp;
			vp->m_NextBlock = pp->m_FirstBlock;
		}
		else
		{
			pp->m_LastBlock->m_NextBlock = vp;
			pp->m_LastBlock = vp;
			vp->m_NextBlock = pp->m_FirstBlock;
		}
		pp->m_BlockCount ++;
		pp->m_freeCount ++;
		return 0;
	};
	int GetMMSGID( char* name, int & id)
	{
		char * sptr = (char*)GetPtr();
		int  size = GetSize();
		if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
		{
			return ERROR_MSGQ_NO1;
		}
		MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef  HRX_MEMERY
		HrxTLockx_Event mksk( GetEventHandle(),200);
		if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
		FUNCTION_LOCK slock(&(pp->m_Lock));
#endif
		for( int i = 0; i < MAX_MSGQ_CNT; i++ )
		{
			if( pp->m_MsgQs[i].m_Status != 0 &&  strcmp(pp->m_MsgQs[i].m_Name,name) == 0 )
			{
				id = i;
				return i;
			}		
		}
		return ERROR_MSGQ_NO6;
	};
	int PrushBackMMSG( int MsgQid, char* buff, int len ) //放入消息队列
	{
		if( MsgQid < 0 || MsgQid >= MAX_MSGQ_CNT || buff == NULL ) return ERROR_MSGQ_NO6;
		char * sptr = (char*)GetPtr();
		int  size = GetSize();
		if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
		{
			return ERROR_MSGQ_NO1;
		}
		MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef  HRX_MEMERY
		HrxTLockx_Event mksk( GetEventHandle(),200);
		if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
		FUNCTION_LOCK slock(&(pp->m_MsgQs[MsgQid].m_Lock));
#endif
		if( pp->m_MsgQs[MsgQid].m_Status == 0 ) return ERROR_MSGQ_NO7;
		if( pp->m_MsgQs[MsgQid].m_WriteCurrent == NULL ) return ERROR_MSGQ_NO8;
		int cnt = len/MAX_BLOCK_SIZE+1;
		if( pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount < cnt ) return ERROR_MSGQ_NO9;
		int clen = len;
		char * cbuff = buff;
		for( int i = 0; i < cnt; i++ )
		{
			MMSG * curt = pp->m_MsgQs[MsgQid].m_WriteCurrent;
			if( clen > MAX_BLOCK_SIZE )
			{
				memcpy( curt->m_Data, cbuff, MAX_BLOCK_SIZE);
				curt->m_DataLength = MAX_BLOCK_SIZE;
				curt->m_InTime = time(0);
				curt->m_MsgFlag = cnt - i; //1 2 3
				cbuff += MAX_BLOCK_SIZE;
				clen -= MAX_BLOCK_SIZE;
			}
			else
			{
				memcpy( curt->m_Data, cbuff, clen);
				curt->m_DataLength = clen;
				curt->m_InTime = time(0);
				curt->m_MsgFlag = cnt - i;
				cbuff += clen;
				clen -= clen;
			}
			pp->m_MsgQs[MsgQid].m_WriteCurrent = (MMSG *)curt->m_NextBlock;
			pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount --;
		}
		return 1;
	};
	int PopFrontMMSG( int MsgQid, char* buff, int Maxlen ) //取出消息
	{
		if( MsgQid < 0 || MsgQid >= MAX_MSGQ_CNT || buff == NULL ) return ERROR_MSGQ_NO6;
		char * sptr = (char*)GetPtr();
		int  size = GetSize();
		if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
		{
			return ERROR_MSGQ_NO1;
		}
		MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef  HRX_MEMERY
		HrxTLockx_Event mksk( GetEventHandle(),200);
		if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
		FUNCTION_LOCK slock(&(pp->m_MsgQs[MsgQid].m_Lock));
#endif
		if( pp->m_MsgQs[MsgQid].m_Status == 0 ) return ERROR_MSGQ_NO7;
		if( pp->m_MsgQs[MsgQid].m_ReadCurrent == NULL ) return ERROR_MSGQ_NO8;
		if( pp->m_MsgQs[MsgQid].m_ReadCurrent->m_MsgFlag == 0 ) return 0; //没有消息
		int cnt = pp->m_MsgQs[MsgQid].m_ReadCurrent->m_MsgFlag;
		char * cbuff = buff;
		int plen = 0;
		for( int i = 0; i < cnt; i++ )
		{
			MMSG * curt = pp->m_MsgQs[MsgQid].m_ReadCurrent;
			if( plen + curt->m_DataLength > Maxlen ) return ERROR_MSGQ_N10; //Maxlen 不够
			if( curt->m_MsgFlag != cnt - i ) return ERROR_MSGQ_N11; //数据已经混乱
			memcpy( cbuff, curt->m_Data, curt->m_DataLength );
			cbuff += curt->m_DataLength;
			plen += curt->m_DataLength;
			pp->m_MsgQs[MsgQid].m_ReadCurrent = (MMSG *)curt->m_NextBlock;
			pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount ++;
		}
		return 1;
	};
	char* GetErrInfo(int err)
	{
		return ERRORINFO[-err-100];
	};
};
[/code]

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧