C 语言中实现环形缓冲区

 更新时间:2016年07月07日 17:33:38   投稿:lqh  
本文主要是介绍 C语言实现环形缓冲区,并附有详细实现代码,具有一定的参考价值,希望能帮助有需要的小伙伴

1.实现代码:

#include 
#include 
#include 
#include 
#include 

#define BUFFSIZE 1024 * 1024 
#define min(x, y) ((x) < (y) ? (x) : (y)) 

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

struct cycle_buffer { 
 unsigned char *buf; 
 unsigned int size; 
 unsigned int in; 
 unsigned int out; 
 pthread_mutex_t lock; 
}; 

static struct cycle_buffer *fifo = NULL; 

static int init_cycle_buffer(void) 
{
 int size = BUFFSIZE, ret; 

 ret = size & (size - 1); 
 if (ret) 
  return ret;
 fifo = (struct cycle_buffer *) malloc(sizeof(struct cycle_buffer)); 
 if (!fifo) 
  return -1; 

 memset(fifo, 0, sizeof(struct cycle_buffer)); 
 fifo->size = size; 
 fifo->in = fifo->out = 0; 
 pthread_mutex_init(&fifo->lock, NULL); 
 fifo->buf = (unsigned char *) malloc(size); 
 if (!fifo->buf)
  free(fifo);
 else
  memset(fifo->buf, 0, size); 
 return 0; 
} 

unsigned int fifo_get(unsigned char *buf, unsigned int len) 
{ 
 unsigned int l; 
 len = min(len, fifo->in - fifo->out); 
 l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); 
 memcpy(buf, fifo->buf + (fifo->out & (fifo->size - 1)), l); 
 memcpy(buf + l, fifo->buf, len - l); 
 fifo->out += len; 
 return len; 
} 

unsigned int fifo_put(unsigned char *buf, unsigned int len) 
{ 
 unsigned int l; 
 len = min(len, fifo->size - fifo->in + fifo->out); 
 l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); 
 memcpy(fifo->buf + (fifo->in & (fifo->size - 1)), buf, l); 
 memcpy(fifo->buf, buf + l, len - l); 
 fifo->in += len; 
 return len; 
} 

static void * thread_read(void *arg) 
{ 
 char buf[1024]; 
 unsigned int n; 
 pthread_detach(pthread_self()); 
 for (;;) { 
  memset(buf, 0, sizeof(buf)); 
  pthread_mutex_lock(&fifo->lock); 
  n = fifo_get(buf, sizeof(buf)); 
  pthread_mutex_unlock(&fifo->lock); 
  write(STDOUT_FILENO, buf, n); 
 }
 printf("nnafter thread_read : %snn",buf);
 return NULL; 
} 

static void * thread_write(void *arg) 
{ 
 unsigned char buf[] = "hello world"; 
 pthread_detach(pthread_self()); 
 for (;;) { 
  pthread_mutex_lock(&fifo->lock); 
  fifo_put(buf, strlen(buf)); 
  pthread_mutex_unlock(&fifo->lock); 
 } 
 return NULL; 
} 

int main(void) 
{ 
 int ret; 
 pthread_t wtid, rtid; 
 ret = init_cycle_buffer(); 
 if (ret == -1) 
  return ret; 

 pthread_create(&wtid, NULL, thread_write, NULL); 
 pthread_create(&rtid, NULL, thread_read, NULL); 
 pthread_exit(NULL); 
 return 0;
}

1.buffer指向存放数据的缓冲区,size是缓冲区的大小,in是写指针下标,out是读指针下标,在len和(fifo->size - fifo->in + fifo->out)之间取一个较小的值赋给len。注意,当(fifo->in == fifo->out+fifo->size)时,表示缓冲区已满,此时得到的较小值一定是0,后面实际写入的字节数也全为0。另一种边界情况是当len很大时(因为len是无符号的,负数对它来说也是一个很大的正数),这一句也能保证len取到一个较小的值,因为fifo->in总是大于等于fifo->out,所以后面的那个表达式的值不会超过fifo->size的大小把上一步决定的要写入的字节数len“切开”,这里又使用了一个技巧。注意:实际分配给fifo->buffer的字节数fifo->size,必须是2的幂,否则这里就会出错。既然fifo->size是2的幂,那么 (fifo->size-1)也就是一个后面几位全为1的数,也就能保证(fifo->in & (fifo->size - 1))总为不超过(fifo->size - 1)的那一部分,和(fifo->in)% (fifo->size - 1)的效果一样。 

 2.这样后面的代码就不难理解了,它先向fifo->in到缓冲区末端这一块写数据,如果还没写完,在从缓冲区头开始写入剩下的,从而实现了循环缓冲。最后,把写指针后移len个字节,并返回len。

 3.从上面可以看出,fifo->in的值可以从0变化到超过fifo->size的数值,fifo->out也如此,但它们的差不会超过fifo->size 。

 以上就是环形缓冲区域的C语言实现详解,希望对大家有所帮助,谢谢支持!

相关文章

  • 图文详解c/c++中的多级指针与多维数组

    图文详解c/c++中的多级指针与多维数组

    多维数组与多级指针是初学者经常感觉迷糊的一个地方。超过二维的数组和超过二级的指针其实并不多用。但只要掌握一定的方法,理解多级指针和“多维”数组完全可以像理解一级指针和一维数组那样简单。
    2016-08-08
  • c语言实现计算圆周率的近似值

    c语言实现计算圆周率的近似值

    这篇文章主要介绍了c语言实现计算圆周率的近似值方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • C语言静态与动态通讯录的实现流程详解

    C语言静态与动态通讯录的实现流程详解

    这篇文章主要为大家介绍了C语言分别实现静态与动态的通讯录示例代码教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • C++图像处理之双边滤波

    C++图像处理之双边滤波

    这篇文章主要为大家详细介绍了C++图像处理之双边滤波,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 简单了解C++常见编程问题解决方案

    简单了解C++常见编程问题解决方案

    这篇文章主要介绍了C++常见编程问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • C语言实现个税计算器

    C语言实现个税计算器

    这篇文章主要为大家详细介绍了C语言实现个税计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++中的基类和派生类构造函数示例详解

    C++中的基类和派生类构造函数示例详解

    这篇文章主要介绍了C++的基类和派生类构造函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • C语言高级教程之变长数组详解

    C语言高级教程之变长数组详解

    这篇文章主要介绍了C语言中变长数组的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • C++浅析虚函数使用方法

    C++浅析虚函数使用方法

    对C++了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。本文就将详细讲讲虚函数表的原理与使用,需要的可以参考一下
    2022-08-08
  • C语言实现财务管理系统

    C语言实现财务管理系统

    这篇文章主要为大家详细介绍了C语言实现财务管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11

最新评论