数据帧缓冲队列(继上一篇的简单队列,改进)(二)

一个简易的数据帧缓冲队列 (一)
数据帧缓冲队列(继上一篇的简单队列,改进)(二)
数据帧缓冲队列(改进,数据可视化)(三)
继上一篇简单队列,进行改进:

1.0  一次性申请空间,避免频繁malloc和free

2.0 多线程可以同时读写 不同的区域

3.0 写数据不会阻塞,覆盖最老的数据

代码:

queue.h

#ifndef  __QUEUE_HEAD_H__
#define __QUEUE_HEAD_H__
#include <pthread.h>
#include <semaphore.h>

typedef unsigned char   uint8_t;     //无符号8位数

#define MIN(a,b) (a)<(b)?(a):(b)
#define SIGLEFRAME_LEN (1024*125) //125K

typedef struct _QUEUE_NODE_
{
	pthread_mutex_t mlock;
	int datalen;
	uint8_t data[SIGLEFRAME_LEN];
} QUEUE_NODE;



class CQueue
{
	public :
		CQueue(int frames);
		~CQueue();
		/*
		*\\ pram: data, the src data, len , the src data lenth
		*\\ return : real  input data lenth
		*/
		int pop(uint8_t *data,int len);

		/*
		* \\no block
		*\\ pram: data, the dest data buffer, len , dest data buffer lenth,
		*\\ return : real  output data lenth
		*/
		int push(uint8_t *data,int len);

		/*	
		* \\ breif :get the data buffer pointer whith block, Manual release is required after use
		*\\  param : **pdata , *plen :the queue data len
		*\\  return -1; no data to get. other the que index will be return ,
		*/
		int getbuffer(uint8_t **pdata,int *plen);
		
		/*
		*\\ breif : get back the que data buffer
		*\\ pram:the que index 
		*\\ return : 0
		*/
		int releasebuffer(int index);

	private:
		void addInindex();
		void addOutindex();
		int IncreaseEffectives();
		int reduceEffectives();
	private:
		int maxFrames;
		QUEUE_NODE *que;
		int mInindex;
		int mOutindex;
		int mEffectives;
		sem_t mSem;

		pthread_mutex_t mIndexlock;
		
	
};
#endif

queue.cpp

#include<stdio.h>
#include<stdlib.h>
#include <string.h>

#include "Queue.h"
#define LOOP_ADD(i,r) ((i)+1)>=(r)?0:(i+1)

#define ERRO_INFO(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#if 1
#define DEBUG(fmt, args...)		do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#else
#define DEBUG(fmt, args...)  
#endif
CQueue::CQueue(int frames):
maxFrames(frames),
mInindex(0),
mOutindex(0),
mEffectives(0)
{	
	que = (QUEUE_NODE *)malloc(frames*sizeof(QUEUE_NODE));
	if(que == NULL)
	{
		printf("erro to malloc\n");
	}
	
	pthread_mutexattr_t mutextattr;
	pthread_mutexattr_init(&mutextattr);
	// 设置互斥锁在进程之间共享
	pthread_mutexattr_setpshared(&mutextattr, PTHREAD_PROCESS_SHARED);
	int i =0;
	for(i=0;i<maxFrames;i++)
	{
		pthread_mutex_init(&que[i].mlock, &mutextattr);
	}
	pthread_mutex_init(&mIndexlock, &mutextattr);
	sem_init(&mSem, 0, 0);
}

CQueue::~CQueue()
{
	int i =0;
	for(i=0;i<maxFrames;i++)
	{
		pthread_mutex_destroy(&que[i].mlock);
	}
	pthread_mutex_destroy(&mIndexlock);
	sem_destroy(&mSem);
	if(que != NULL)
	{
		free(que);
		que = NULL;
	}
}
int CQueue::pop(uint8_t *data,int len)
{
	//DEBUG("in %d out %d len %d\n ",mInindex,mOutindex,len);
	
	//sem_wait(&mSem);
	sem_trywait(&mSem);
	int iout = mOutindex;
	
	pthread_mutex_t * ilock = &que[iout].mlock;
	pthread_mutex_lock(ilock);
	
	if(reduceEffectives() ==0)
	{	
		mEffectives = 0;
		pthread_mutex_unlock(ilock);
		DEBUG("no data\n");
		return 0;
	}
	
	int copylen = MIN(len,que[iout].datalen);
	if(data != NULL)
	{
		memcpy(data,que[iout].data,copylen);
	}
	
	addOutindex();
	pthread_mutex_unlock(ilock);
	return copylen;
}

int CQueue::push(uint8_t *data,int len)
{
	//DEBUG("in %d out %d len %d\n ",mInindex,mOutindex,len);
	int iIn = mInindex;
	pthread_mutex_t * ilock = &que[iIn].mlock;
	
	pthread_mutex_lock(ilock);
	int copylen = MIN(len,sizeof(que[iIn].data));
	
	if(data != NULL)
	{
		memcpy(que[iIn].data,data,copylen);
		que[iIn].datalen = copylen;
	}
	
	addInindex();
	sem_post(&mSem);
	if(IncreaseEffectives() == maxFrames)
	{//覆盖老数据
		DEBUG("cover  mEffectives %d ,maxFrames %d\n",mEffectives,maxFrames);
		//DEBUG("cover  mInindex %d ,mOutindex %d\n",mInindex,mOutindex);
		sem_trywait(&mSem);
		addOutindex();
	}
	pthread_mutex_unlock(ilock);
	

	return copylen;

}

int CQueue::getbuffer(uint8_t **pdata,int *plen)
{
	int val=0;
	sem_wait(&mSem);
	int iout = mOutindex;

	pthread_mutex_t * ilock = &que[iout].mlock;
	pthread_mutex_lock(ilock);
	//DEBUG("pop  mEffectives %d ,maxFrames %d\n",mEffectives,maxFrames);
	
	if(reduceEffectives() ==0 )
	{	
		*pdata = NULL;
		*plen =  0;
		pthread_mutex_unlock(ilock);
		DEBUG("no data\n");
		return -1;
	}

	*pdata = que[iout].data;
	*plen =  que[iout].datalen;
	
	addOutindex();
	//DEBUG("in %d out %d len %d unlock \n ",mInindex,mOutindex,len);
	//pthread_mutex_unlock(ilock);
	
	//DEBUG("get index  %d \n",iout);
	return iout;
}
int CQueue::releasebuffer(int index)
{
	//DEBUG("releas %d \n",index);
	if(0 <= index && index < maxFrames)
	{
		pthread_mutex_unlock(&que[index].mlock);
	}
	return 0;
}


void CQueue::addInindex()
{
	pthread_mutex_lock(&mIndexlock);
	mInindex = LOOP_ADD(mInindex,maxFrames);
	pthread_mutex_unlock(&mIndexlock);
}
void CQueue::addOutindex()
{
	pthread_mutex_lock(&mIndexlock);
	mOutindex = LOOP_ADD(mOutindex,maxFrames);
	pthread_mutex_unlock(&mIndexlock);
}

int CQueue::IncreaseEffectives()
{
	pthread_mutex_lock(&mIndexlock);
	int ret = mEffectives;
	mEffectives += 1;
	if(mEffectives > maxFrames)
	{	
		mEffectives = maxFrames;
	}
	pthread_mutex_unlock(&mIndexlock);
	return ret;
}

int CQueue::reduceEffectives()
{
	pthread_mutex_lock(&mIndexlock);
	
	int ret = mEffectives;
	mEffectives -= 1;
	if(mEffectives<0)
	{	
		mEffectives = 0;
	}
	pthread_mutex_unlock(&mIndexlock);
	return ret;
}


#if 0
int main()
{

	CQueue * pQueue = new CQueue(3);

	uint8_t buf1[128]="11111";
	uint8_t buf2[128]="22222";
	uint8_t buf3[128]="33333";
	uint8_t buf4[128]="44444";
	uint8_t buf5[128]="55555";
	uint8_t bufget[128]={0};
	
	int len = sizeof(bufget);
	pQueue->push(buf1,sizeof(buf1));
	#if 1
	pQueue->push(buf2,sizeof(buf2));
	pQueue->push(buf3,sizeof(buf3));
	pQueue->push(buf4,sizeof(buf4));
	pQueue->push(buf5,sizeof(buf5));

	pQueue->pop(bufget,len);
	printf("wang bufget :%s \n",bufget);

	pQueue->pop(bufget,len);
	printf("wang bufget :%s \n",bufget);
	
	pQueue->pop(bufget,len);
	printf("wang bufget :%s \n",bufget);
	
	pQueue->pop(bufget,len);
	printf("wang bufget :%s \n",bufget);

	
	pQueue->pop(bufget,len);
	printf("wang bufget :%s \n",bufget);


	//pQueue->push(buf1,sizeof(buf1));
	//len = sizeof(bufget);
	#endif
	//pQueue->pop(bufget,len);
	//printf("wang bufget :%s \n",bufget);
	
	delete pQueue;

	return 0;
}
#endif


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值