Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12876692
  • 博文数量: 1293
  • 博客积分: 13501
  • 博客等级: 上将
  • 技术积分: 17974
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 18:11
文章分类

全部博文(1293)

文章存档

2019年(1)

2018年(1)

2016年(118)

2015年(257)

2014年(128)

2013年(222)

2012年(229)

2011年(337)

分类: LINUX

2011-03-25 21:42:03

1、环形缓冲区ringbuffer原理

 

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

 

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

 

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

 

   
 
 
2、dyli修改版程序
 
  1. /********************ringbuf .c*************************/

  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #define MAXNUM 3

  5. int currentInputPlace=0;//环形缓冲区的当前放入位置,初始为0

  6. int currentOutputPlace=0;//环形缓冲区的当前取出位置,初始为0

  7. int n=0;    //环形缓冲区中的当前可用元素的总数量,初始为0

  8. double buffer[MAXNUM];


  9. /***************************************************************************************************
  10.     环形缓冲区的地址编号计算函数,如果到达唤醒缓冲区的尾部 ,将绕回头部。
  11.     环形缓冲区的有效地址编号为:0-->(MAXNUM-1)
  12. **************************************/
  13. int addMemberToRing(int i)
  14. {
  15.     return (i+1) == MAXNUM?0:i+1;
  16.                                     /*是否到环形的尾部,是:返回0;否:返回一个缓冲区的编号*/
  17. }


  18. /**************************************************************************************************
  19.     从环形缓冲区中取一个元素
  20. *************************************/
  21. double get(void)
  22. {
  23.     int pos;
  24.     if(n>0)
  25.     {
  26.         pos=currentOutputPlace;//从第0个位置开始

  27.         currentOutputPlace=addMemberToRing(currentOutputPlace);//

  28.         n--;    //当前可用元素少一个

  29.         return buffer[pos];
  30.     }
  31.     else
  32.     {
  33.         printf("dyli find Buffer is empty \n");
  34.         return 0.0;
  35.     }
  36. }


  37. /**************************************************************************************************
  38.     向环形缓冲区放入一个元素    
  39. *************************************/
  40. void put(double z)
  41. {
  42.     if(n<MAXNUM)
  43.     {
  44.         buffer[currentInputPlace]=z;//将元素填入

  45.         currentInputPlace=addMemberToRing(currentInputPlace);//当前输入位置下移一个

  46.         n++;//当前可用元素多一个

  47.     }
  48.     else//达到8个则提醒缓冲区已满

  49.     {
  50.         printf("dyli find Buffer is full \n");
  51.     }
  52. }


  53. /**************************************************************************************************
  54.     main()    
  55. *************************************/
  56. int main(void)
  57. {
  58.     char opera[5];
  59.     double z;
  60.     do{
  61.         printf("dyli ask you to input p|g|e?");
  62.         scanf("%s",&opera);
  63.         switch(tolower(opera[0]))//函数将tolower()可以将字符串转换成小写字母

  64.         {
  65.             case 'p':/* put */
  66.                     printf("Please input a float number:");
  67.                     scanf("%lf",&z);
  68.                     put(z);
  69.                     break;
  70.             case 'g':/* get */
  71.                     z=get();
  72.                     printf("%8.2f from buffer \n",z);
  73.                     break;
  74.             case 'e':
  75.                     printf("dyli say :The end.\n");
  76.                     break;
  77.             default :
  78.                     printf("%s --yout operator command error !\n",opera);                
  79.         }/*end of switch*/
  80.     }while(opera[0]!='e');
  81.     return 0;
  82. }

 

运行结果:

[root@localhost ringbuf]# ./ringbuf

dyli ask you to input p|g|e?p

Please input a float number:1

dyli ask you to input p|g|e?p

Please input a float number:2

dyli ask you to input p|g|e?p

Please input a float number:3

dyli ask you to input p|g|e?p

Please input a float number:4

dyli find Buffer is full

dyli ask you to input p|g|e?g

    1.00 from buffer

dyli ask you to input p|g|e?g

    2.00 from buffer

dyli ask you to input p|g|e?g

    3.00 from buffer

dyli ask you to input p|g|e?g

dyli find Buffer is empty

    0.00 from buffer

dyli ask you to input p|g|e?e

dyli say :The end.

[root@localhost ringbuf]#

 
阅读(3564) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~