FIFO环形缓冲区的实现

在不同的系统之间交换数据时,往往由于两个系统时间不能完全同步。

为了保证生产者和消费者的同步,需要使用环形缓冲区。生产者以某一速度存入数据,消费者以某一速度取出数据,两者的速度不用时刻一致,但总体的平均速度必须相等!

以下是具体实现:

/**************FIFO Begin**************************************************/
/*溢出标志:0-正常,-1-溢出*/  
#define FLAGS_OVERRUN 0x0001  
/*  
        buf- 缓冲区地址  
        size- 大小  
        free- 空余容量  
        putP- 下一个数据写入位置  
        getP- 下一个数据独处位置  
*/  
struct FIFO8{  
         char *buf;  
         int putP,getP,size,free,flags;  
		 pthread_mutex_t mutex;
};  
  
int fifo8_init(struct FIFO8 *fifo,int size);  
int fifo8_put(struct FIFO8 *fifo, char data);  //not mutiply thread safe
int fifo8_get(struct FIFO8 *fifo);     //not mutiply thread safe
void fifo8_status(struct FIFO8 *fifo,int *len);  
void fifo8_free(struct FIFO8 *fifo,int *len);  
int fifo8_write(struct FIFO8 *fifo,char *data,int len);
int fifo8_read(struct FIFO8 *fifo,char *data,int len);

/*初始化*/ 
int  fifo8_init(struct FIFO8 *fifo,int size) {  
	
	int ret=0;

	fifo->flags=0;            
	fifo->free=size;  
	fifo->size=size;  
	fifo->putP=0;                     
	fifo->getP=0;  
	
	fifo->buf=(char *)malloc(size);
	if(fifo->buf==NULL){
		LOGI("malloc fifo buffer failed!\n");
		return -1;
	}
	
	ret = pthread_mutex_init(&(fifo->mutex),NULL);
	if(ret <0){
		LOGI("init mutex failed!\n");
		return -1;
	}

	return 0;   
}  

/*向FIFO 中写入1个数据 */  
int fifo8_putPut(struct FIFO8 *fifo, char data)  {  
	if(fifo->free==0){  
		fifo->flags |= FLAGS_OVERRUN;  
		return -1;  
	}  
	fifo->buf[fifo->putP] = data;  
	fifo->putP++;  
	//循环队列缓冲区  
	if(fifo->putP == fifo->size){  
		fifo->putP = 0;  
	}  
	fifo->free--;  

	return 0;  
}  
/*从FIFO 中取出一个数据 */
int fifo8_get(struct FIFO8 *fifo)  {  
	int data;  
	if(fifo->free == fifo->size){  
		return -1;  
	}  
	
	data = fifo->buf[fifo->getP++];  
	//fifo->getP++;  
	if(fifo->getP == fifo->size){//用来实现循环  
		fifo->getP = 0;  
	}  
	fifo->free++;  
	return data;  
}  
/*写入len个字节,返回写入的字节数*/
int fifo8_write(struct FIFO8 *fifo,char *data,int len){
	
	int i=0;
	pthread_mutex_lock(&(fifo->mutex));
	
	if(fifo->free < len) {
		pthread_mutex_unlock(&(fifo->mutex));	
		LOGI("the free size in not enough!\n");
		return 0;
	}
	else {
		LOGI("current fifo->putP =%d \n",fifo->putP);
		for(i=0;i<len;i++){
			fifo->buf[fifo->putP++] = *(data+i);  
			//循环队列缓冲区  
			if(fifo->putP == fifo->size){  
				fifo->putP = 0;  
			}  
			fifo->free--;  
		}
	}

	pthread_mutex_unlock(&(fifo->mutex));	
	
	return len;
}
/*读出len个字节,返回读出的字节数*/
int fifo8_read(struct FIFO8 *fifo,char *data,int len){
	
	int i=0;
	pthread_mutex_lock(&(fifo->mutex));
	
	if(fifo->size!=fifo->free){
		LOGI("current fifo->getP =%d \n",fifo->getP);
		for(i=0;  ; i++){
			*(data+i) =fifo->buf[fifo->getP++];  
			if(fifo->getP == fifo->size){//用来实现循环  
				fifo->getP = 0;  
			}  
			fifo->free++;  
			if(fifo->size==fifo->free){
				LOGI("the buffer is no data left!\n");
				pthread_mutex_unlock(&(fifo->mutex));
				return i+1;
			}
			if(i+1==len){
				LOGI("read data finish!\n");
				break;
			}
		}
	}
	else{
		LOGI("the buffer is empty!\n");
		pthread_mutex_unlock(&(fifo->mutex));	
		return 0;
	}
	
	pthread_mutex_unlock(&(fifo->mutex));	
	
	return len;
}

/*缓冲区被使用容量*/  
void fifo8_status(struct FIFO8 *fifo,int *used)  {  
	pthread_mutex_lock(&(fifo->mutex));
	*used = fifo->size - fifo->free; 
	pthread_mutex_unlock(&(fifo->mutex));	
}  
/*缓冲区剩余容量*/
void fifo8_free(struct FIFO8 *fifo ,int *free)  { 
	pthread_mutex_lock(&(fifo->mutex)); 
	*free = fifo->free;  
	pthread_mutex_unlock(&(fifo->mutex));
}


  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值