博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
环形缓冲区
阅读量:6176 次
发布时间:2019-06-21

本文共 1579 字,大约阅读时间需要 5 分钟。

在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。

1、环形缓冲区的实现原理

环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写人。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。

1、图2和图3是一个环形缓冲区的运行示意图。图1是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;图2是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块2的位置,而读指针没有移动;图3是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,已经读取了一个数据。

2、实例:环形缓冲区的实现

环形缓冲区是数据通信程序中使用最为广泛的数据结构之一,下面的代码,实现了一个环形缓冲区:

ExpandedBlockStart.gif
/*
ringbuf .c
*/
None.gif
None.gif#i nclude<stdio. h>
None.gif
None.gif    #i nclude<ctype. h>
None.gif
None.gif
#define NMAX 8
None.gif
ExpandedBlockStart.gif
int iput = 0; 
/*
 环形缓冲区的当前放人位置 
*/
None.gif
ExpandedBlockStart.gif
int iget = 0; 
/*
 缓冲区的当前取出位置 
*/
None.gif
ExpandedBlockStart.gif
int n = 0; 
/*
 环形缓冲区中的元素总数量 
*/
None.gif
None.gif
double buffer[NMAX]; 
None.gif
ExpandedBlockStart.gif
/*
  环形缓冲区的地址编号计算函数,,如果到达唤醒缓冲区的尾部,将绕回到头部。
InBlock.gif
InBlock.gif环形缓冲区的有效地址编号为:0到(NMAX-1)
InBlock.gif
ExpandedBlockEnd.gif
*/
None.gif
None.gif
int addring (
int i)
None.gif
ExpandedBlockStart.gif {
InBlock.gif
InBlock.gif        
return (i+1) == NMAX ? 0 : i+1;
InBlock.gif
ExpandedBlockEnd.gif}
None.gif
ExpandedBlockStart.gif
/*
 从环形缓冲区中取一个元素 
*/
None.gif
ExpandedBlockStart.gif
double 
get {
void}
None.gif
ExpandedBlockStart.gif {
InBlock.gif
InBlock.gifcnt pos;
InBlock.gif
ExpandedSubBlockStart.gif
if (n>0){
InBlock.gif
InBlock.gif           Pos = iget;
InBlock.gif
InBlock.gif           iget = addring(iget);
InBlock.gif
InBlock.gif           n--;
InBlock.gif
InBlock.gif           
return buffer[pos];
InBlock.gif
ExpandedSubBlockEnd.gif}
InBlock.gif
ExpandedSubBlockStart.gif
else {
InBlock.gif
InBlock.gifprintf(“Buffer 
is empty\n”);
InBlock.gif
InBlock.gif
return 0.0;
InBlock.gif
ExpandedSubBlockEnd.gif}
InBlock.gif
ExpandedSubBlockStart.gif
/*
 向环形缓冲区中放人一个元素
*/
InBlock.gif
InBlock.gif
void put(
double z)
InBlock.gif
ExpandedSubBlockStart.gif{
InBlock.gif
ExpandedSubBlockStart.gif
if (n<NMAX){
InBlock.gif
InBlock.gif           buffer[iput]=z;
InBlock.gif
InBlock.gif           iput = addring(iput);
InBlock.gif
InBlock.gif           n++;
InBlock.gif
ExpandedSubBlockEnd.gif}
InBlock.gif
InBlock.gif
else
InBlock.gif
InBlock.gifprintf(“Buffer 
is full\n”);
InBlock.gif
ExpandedSubBlockEnd.gif}
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gif
int main{
void)
InBlock.gif
ExpandedSubBlockStart.gif{
InBlock.gif
InBlock.gifchat opera[5];
InBlock.gif
InBlock.gif
double z;
InBlock.gif
ExpandedSubBlockStart.gif
do {
InBlock.gif
InBlock.gifprintf(“Please input p|g|e?”);
InBlock.gif
InBlock.gifscanf(“%s”, &opera);
InBlock.gif
ExpandedSubBlockStart.gif               
switch(tolower(opera[0])){
InBlock.gif
ExpandedSubBlockStart.gif               
case ‘p’: 
/*
 put 
*/
InBlock.gif
InBlock.gif                  printf(“Please input a 
float number?”);
InBlock.gif
InBlock.gif                  scanf(“%lf”, &z);
InBlock.gif
InBlock.gif                  put(z);
InBlock.gif
InBlock.gif                  
break;
InBlock.gif
ExpandedSubBlockStart.gif
case ‘g’: 
/*
 get 
*/
InBlock.gif
InBlock.gif                  z = 
get();
InBlock.gif
InBlock.gifprintf(“%8.2f from Buffer\n”, z);
InBlock.gif
InBlock.gif
break;
InBlock.gif
InBlock.gif
case ‘e’:
InBlock.gif
InBlock.gif                  printf(“End\n”);
InBlock.gif
InBlock.gif                  
break;
InBlock.gif
InBlock.gif
default:
InBlock.gif
InBlock.gif                  printf(“%s - Operation command error! \n”, opera);
InBlock.gif
ExpandedSubBlockStart.gif}
/*
 end switch 
*/
InBlock.gif
ExpandedSubBlockEnd.gif}
while(opera[0] != ’e’);
InBlock.gif
InBlock.gif    
return 0;
InBlock.gif
ExpandedSubBlockEnd.gif}
InBlock.gif

转载地址:http://fnhba.baihongyu.com/

你可能感兴趣的文章
移动端配适与掌握动态 REM
查看>>
用Node.js爬取动态网页,这可能是最简洁的方式
查看>>
人月神话阅读笔记2
查看>>
js作用域
查看>>
css3 text-shadow
查看>>
Java VM里的magic
查看>>
java8新特性
查看>>
IDEA 2017的插件mybatis plugin(绿色免安装)
查看>>
最长回文子串
查看>>
phpcms v9的默认模板导出的json文本
查看>>
菜鸟装机大杂烩
查看>>
JS的parent对象
查看>>
论坛中常有的提问,评论,点赞设计
查看>>
Maven将jar包放入本地库
查看>>
js delete 用法(删除对象属性及变量)
查看>>
链接记录
查看>>
洛谷P4137 Rmq Problem / mex(莫队)
查看>>
基本算法之冒泡排序
查看>>
python any and all function
查看>>
运维之linux基础知识(一)
查看>>