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

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

在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法,

当读取速度大于写入速度时,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外)。

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

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

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

图 1、图 2 和图 3 是一个环形缓冲区的运行示意图。

图1 初始状态

图二 向环形缓冲区中添加了一个数据

图三环形缓冲区进行了读取和添加

图 1 是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;

图 2 是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块 2 的位置,而读指针没有移动;

图 3 是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,已经读取了一个数据。

 这个只是示意图

下面是用写的代码:

[cpp]   
 
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #define MAXSIZE 8  
  4. int ringbuf[MAXSIZE];  
  5. int realdx = 0;  
  6. int writeldx = 0;  
  7. int next_data_handle(int addr)  
  8. {  
  9.         return (addr+1) == MAXSIZE ? 0 : (addr + 1);  
  10. }  
  11. int write_data(int data)  
  12. {  
  13.         int i;  
  14.         *(ringbuf+writeldx)=data;  
  15.         writeldx = next_data_handle(writeldx);  
  16.         for(i = 0; i < MAXSIZE; i++)  
  17.         {  
  18.                 printf("%4d\t",*(ringbuf + i ));  
  19.                 if(MAXSIZE-1 == i)  
  20.                 printf("\n");  
  21.   
  22.         }  
  23. }  
  24. int read_data()  
  25. {  
  26.         printf("read data is : %d\t",*(ringbuf + realdx));  
  27.         realdx = next_data_handle(realdx);  
  28. }  
  29. int main(int argc, char *argv)  
  30. {  
  31.         int data;  
  32.         char cmd;  
  33.   
  34.         do{  
  35.         printf("select:\tw--write:\tr--read:\tq--quit\n");  
  36.         scanf("%s",&cmd);  
  37.         switch(cmd)  
  38.         {  
  39.                 case 'w':  
  40.                 printf("please input data:");  
  41.                 scanf("%d",&data);  
  42.                 write_data(data);  
  43.                 break;  
  44.                 case 'r':  
  45.                 data = read_data();  
  46.                 printf("read all \n");  
  47.                 break;  
  48.                 case 'q':  
  49.                 printf("quit\n");  
  50.                 break;  
  51.                 default:  
  52.                 printf("Command error\n");  
  53.                 break;  
  54.         }  
  55.         }while(cmd!='q');  
  56.         return 0;  
  57. }  

执行的结果如下:

主要是要理解这个环形设计的思想。

转自:http://blog.csdn.net/u011046042/article/details/51853535

转载于:https://www.cnblogs.com/alan666/p/8311960.html

你可能感兴趣的文章
数据持久化时的小bug
查看>>
http://www.bootcss.com/
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
C语言栈的实现
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
使用命令创建数据库和表
查看>>
【转】redo与undo
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>
Oracle事务
查看>>
String类中的equals方法总结(转载)
查看>>
标识符
查看>>
内存地址对齐
查看>>
创新课程管理系统数据库设计心得
查看>>
Could not resolve view with name '***' in servlet with name 'dispatcher'
查看>>
[转载] redis 的两种持久化方式及原理
查看>>
MyBaits学习
查看>>
管道,数据共享,进程池
查看>>