环形缓冲区的C语言实现
来源:互联网 发布:打开后缀unity3d文件 编辑:程序博客网 时间:2024/06/03 15:59
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#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;
}
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#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;
}
- 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)的效果一样。
- 这样后面的代码就不难理解了,它先向fifo->in到缓冲区末端这一块写数据,如果还没写完,在从缓冲区头开始写入剩下的,从而实现了循环缓冲。最后,把写指针后移len个字节,并返回len。
- 从上面可以看出,fifo->in的值可以从0变化到超过fifo->size的数值,fifo->out也如此,但它们的差不会超过fifo->size 。
0
上一篇:SPI读写总结
下一篇:c疑难点
相关热门文章
- test123
- 编写安全代码——小心有符号数...
- 使用openssl api进行加密解密...
- 一段自己打印自己的c程序...
- sql relay的c++接口
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
0 0
- 环形缓冲区的C语言实现
- 环形缓冲区的c实现
- C语言 环形缓冲区
- 环形缓冲区的实现
- 环形缓冲区的实现
- 环形缓冲区的实现
- 环形缓冲区的实现
- 【数据结构】环形缓冲区/循环队列 C语言实现
- 环形缓冲区的实现原理
- 环形缓冲区的实现原理
- 环形缓冲区的实现原理
- 环形缓冲区的实现原理
- FIFO环形缓冲区的实现
- 环形缓冲区的实现原理
- 环形缓冲区的实现原理
- C语言实现的环形队列
- linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)
- 一个简单的环形缓冲区的实现
- linux设备驱动归纳总结(四):5.SMP下的竞态和并发
- 用户空间和内核空间通讯之【proc文件系统】
- 嵌入式C编程经验 之 全局变量猛于虎
- linux设备驱动归纳总结(三):6.poll和sellct
- SPI读写总结
- 环形缓冲区的C语言实现
- c疑难点
- linux C 中常用的字符串操作函数
- c库函数
- Linux内核线程
- GPIO中断
- linux中断流程详解
- Swift之可选数据类型
- Unity Shaders and Effects Cookbook (3-1) 使用Unity 内置的Specular Lighting - BlinnPhong
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
向幸福前进考试交白卷
向伟大复兴前进
向着炮火前进全集
前进蒸汽机车
前进的反义词
前进的近义词
向着胜利前进全集播放
杭齿前进股票
前进轮胎质量怎么样
前进远卓教育培训中心
前进家具乌金木图片欣赏
前进轮胎700r16
向着目标前进
前进用英语怎么说
前进的反义词是什么
杭齿前进股吧
前进压瓦机厂
前进家具图片
向这胜利前进
向着炮火前进下载
向着炮火前进向着胜利前进
前进轮胎怎么样
向着胜利前进和向着炮火前进
前进叉车轮胎
向着炮火前进 tv版
前途k50
前途无量
前途汽车
前途似海
辅警前途
会计前途
前途的意思
前途的图片
前途汽车k50
前途车
有前途
美工的前途
程序员 前途
前途迷茫
前途渺茫
没前途