环形缓冲区的实现原理 在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。
1、环形缓冲区的实现原理
环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。
图1、图2和图3是一个环形缓冲区的运行示意图。图1是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;图2是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块2的位置,而读指针没有移动;图3是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,已经读取了一个数据。
file:///C:/Users/Administrator/AppData/Roaming/Tencent/Users/402043411/QQ/WinTemp/RichOle/Y_8MKCS%60)HWMTF8P$%7D%7DIP%7BJ.jpg 2、实例:环形缓冲区的实现
环形缓冲区是数据通信程序中使用最为广泛的数据结构之一,下面的代码,实现了一个环形缓冲区:
/*ringbuf .c*/ #include<stdio. h> #include<ctype. h> #define NMAX 8
int iput = 0; /* 环形缓冲区的当前放入位置 */ int iget = 0; /* 缓冲区的当前取出位置 */ int n = 0; /* 环形缓冲区中的元素总数量 */ double buffer[NMAX];
/* 环形缓冲区的地址编号计算函数,如果到达唤醒缓冲区的尾部,将绕回到头部。
环形缓冲区的有效地址编号为:0到(NMAX-1) */
int addring (int i) {
return (i+1) == NMAX ? 0 : i+1; }
/* 从环形缓冲区中取一个元素 */ double get(void) {
int pos; if (n>0){
Pos = iget;
iget = addring(iget); n--;
return buffer[pos];
} else {
printf(“Buffer is emptyn”); return 0.0; }
/* 向环形缓冲区中放入一个元素*/ void put(double z) {
if (n<NMAX){
buffer[iput]=z; iput = addring(iput);
n++;
} else
printf(“Buffer is fulln”);
}
int main{void) {
chat opera[5]; double z; do {
printf(“Please input p|g|e?”); scanf(“%s”, &opera);
switch(tolower(opera[0])){
case „p‟: /* put */
printf(“Please input a float number?”); scanf(“%lf”, &z); put(z); break;
case „g‟: /* get */
z = get();
printf(“%8.2f from Buffern”, z);
break;
case „e‟:
printf(“Endn”); break;
default:
printf(“%s - Operation command error! n”, opera);
}/* end switch */ }while(opera[0] != ‟e‟);
return 0; }
补充内容 (2013-11-12 14:53):
http://wenku.baidu.com/view/e73ee13843323968011c92d7.html
补充内容 (2013-11-12 14:56):
STM32串口驱动(拼音检索测试通过)(环形队列+内存动态分配+DMA) 有源吗可供下载,哈哈~
http://www.amobbs.com/thread-4516795-1-1.html |