ringbuffer的常规用法_c语言fputs

ringbuffer的常规用法_c语言fputs一、ringBuffer介绍ringBuffer称作环形缓冲,也有叫circleBuffer的。就是取内存中一块连续的区域用作环形缓冲区的数据存储区。这块连续的存储会被反复使用,向ringBuffer写入数据总是从写指针的位置开始,如写到实际存储区的末尾还没有写完,则将剩余的数据从存储区的头开始写;从该ringBuffer读出数据也是从读指针的位置开始,如读到实际存储区的末尾…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、 ringBuffer 介绍

ringBuffer 称作环形缓冲,也有叫 circleBuffer 的。就是取内存中一块连续的区域用作环形缓冲区的数据存储区。这块连续的存储会被反复使用,向 ringBuffer 写入数据总是从写指针的位置开始,如写到实际存储区的末尾还没有写完,则将剩余的数据从存储区的头开始写;从该 ringBuffer 读出数据也是从读指针的位置开始,如读到实际存储区的末尾还没有读完,则从存储区的头开始读剩下的数据。

为了保证写入的数据不会覆盖 ringBuffer 里还没有被读出的数据,以及读出的数据不是已经读出过的旧数据,需要使用一个变量 btoRead 表示该 ringBuffer 中有效的数据。使用变量 length 表示该环形缓冲区中真实的缓冲大小。使用指针 source 指向实际的缓存地址。

使用 ringBuffer 读写数据,要确保读写数据的速率和实际缓冲区大小的匹配。如果不匹配,可能会导致溢出,比如读数据太慢,而写数据很快,实际的缓存区又太小,导致整个缓冲区都是还没有被读出的数据,此时新的数据就无法写入。正确使用 ringBuffer 可以保证数据的连续,降低读模块和写模块之间的耦合性。更多关于生产者-消费者模型的知识可以看这篇博客

二、代码

ringBuffer 的结构体

typedef struct { 
   
    uint8_t *source;
    uint32_t br;
    uint32_t bw;
    uint32_t btoRead;
    uint32_t length;
}ringbuffer_t;

创建 ringBuffer 函数

void create_ringBuffer(ringbuffer_t *ringBuf, uint8_t *buf, uint32_t buf_len)
{ 
   
	ringBuf->br         = 0;
	ringBuf->bw         = 0;
	ringBuf->btoRead    = 0;
	ringBuf->source     = buf;
	ringBuf->length     = buf_len;
	printf("create ringBuffer->length = %d\n", ringBuf->length);
}

清空 ringBuffer 函数

void clear_ringBuffer(ringbuffer_t *ringBuf)
{ 
   
	ringBuf->br         = 0;
	ringBuf->bw         = 0;
	ringBuf->btoRead    = 0;
	
	//no need do this casue r_ptr and w_prt has change
// memset((uint8_t *)ringBuf->source, 0, ringBuf->length); 
}

读数据函数

uint32_t write_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
{ 
   
	uint32_t len            = 0;
	uint32_t ringBuf_bw     = ringBuf->bw;
	uint32_t ringBuf_len    = ringBuf->length;
	uint8_t *ringBuf_source = ringBuf->source;
	
	if( (ringBuf_bw + size) <= ringBuf_len  )
	{ 
   
		memcpy(ringBuf_source + ringBuf_bw, bufff, size);
	}
	else
	{ 
   
		len = ringBuf_len - ringBuf_bw;
		memcpy(ringBuf_source + ringBuf_bw, buffer, len);
		memcpy(ringBuf_source, buffer + len, size - len);
	}

	ringBuf->bw = (ringBuf->bw + size) % ringBuf_len;
	ringBuf->btoRead += size;

	return size;
}

写数据函数

uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
{ 
   
	uint32_t len            = 0;
	uint32_t ringBuf_br     = ringBuf->br;
	uint32_t ringBuf_len    = ringBuf->length;
    uint8_t *ringBuf_source = ringBug->source;

	if( (ringBuf_br + size ) <= ringBuf_len )
	{ 
   
		memcpy(buffer, ringBuf_source + ringBuf_br, size);
	}
	else
	{ 
   
		len = ringBuf_len - ringBuf_br;
		memcpy(bufff, ringBuf_source + ringBuf_br, len);
		memcpy(buffer + len, ringBuf_source, size - len);
	}

	ringBuf->br = (ringBuf->br + size) % ringBuf_len;
	ringBuf->btoRead -= size;

	return size;
}

获取 ringBuffer 中的有效数据

uint32_t get_ringBuffer_btoRead(ringbuffer_t *ringBuf)
{ 
   
	return ringBuf->btoRead;
}

获取 ringBuffer 的长度

uint32_t get_ringBuffer_length(ringbuffer_t *ringBuf)
{ 
   
	return ringBuf->length;
}

三、使用方法

对 ringBuffer 的使用,首先需要又一块真实并且连续的数据存储区。可以使用 malloc 从堆区分配,也可以使用一个数组。

在写数据之前,需要对此时 ringBuffer 的剩余空间和要写入数据的大小进行比较。剩余空间使用长度 length 减去待读出数据量 btoRead 得到。

在读出数据之前,则需要对此时 ringBuffer 可读出的有效数据 btoRead 进行判断。

读出的数据不够,或者没有足够的空间写如数据,可以在调用读写函数之前进行判断,假如情况不满足,就不调用相应的读写函数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195019.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • win10-11全版本下载地址MSDN纯净版ISO-20220217更新[通俗易懂]

    win10-11全版本下载地址MSDN纯净版ISO-20220217更新[通俗易懂]本文搜集整理微软官方发布的Windows10正式版镜像下载链接,从RTM原始正式版开始,按照时间倒序排列,即越往上的越新。转载:http://news.mydrivers.com/1/440/440540.htm谨记:不管从什么地方下载,文件名可以不一样,但是体积、SHA1校验码必须一致,尤其是后者,有一点不同的也不要安装。下载链接均为ed2kP2P方式,使用迅雷即可。

    2022年7月20日
    32
  • url的加密解密_url地址加密

    url的加密解密_url地址加密今天做项目构造链接参数的时候,推送到app上的链接点了没办法跳转到对应的界面对比了一下能跳转的链接,原来是url没有加密,就推送过去了在这里把对url加密解密的方法记录一下,方便以后使用publicstaticStringgetURLEncoderString(Stringstr){Stringresult="";if(null==str){…

    2025年7月2日
    3
  • nessus安装教程_kali安装nessus

    nessus安装教程_kali安装nessus(Windows安装教程)step1.官网下载对应操作系统安装包https://www.tenable.com/downloads/nessus1.pngstep2.正常双击程序安装等到最后一步finish完成后等会自动跳转出一个注册页面,或者打开浏览器输入https://localh…

    2022年10月10日
    3
  • python收集数据做主神_里纲_[综漫]收集数据做主神小说无防盗章节_作者忘却的悠_新书包网(www.51aslz.com)…[通俗易懂]

    python收集数据做主神_里纲_[综漫]收集数据做主神小说无防盗章节_作者忘却的悠_新书包网(www.51aslz.com)…[通俗易懂]“里包恩怎么了?”“没什么,只是在想,你做为里包恩的学生,能不能帮我个忙?”“帮忙?”纲不好意思的抓了抓头发,所有的心思都写在了脸上。什么我这么废柴能帮什么忙,虽然我很想帮忙,但是我真的什么都做不好。找里包恩本人更快吧,实在不行还有山本和狱寺他们。不过……库洛洛先生是黑手党吧?黑手党的事情,我们几个小孩子能帮什么忙呢?果然还是找里包恩比较好。能把心思在脸上表达的这么明明白白,你也算…

    2022年4月19日
    48
  • C#MQTTNET客户端使用说明

    C#MQTTNET客户端使用说明C#MQTTNET客户端使用说明1.如何使用1.我想启动MQTT客户端,我该怎么做?2.我想收到服务器发来消息,我该怎么做?3.我想知道客户端是否连接成功,我该怎么做?3.我想知道怎样重连服务器,我该怎么做?1.如何使用1.我想启动MQTT客户端,我该怎么做?try{IMqttClientclient=newMqttFactory().CreateMqttClient();varbuild=newMqttClientOptionsBuilder()//配

    2022年6月25日
    66
  • Redis lock_lock锁机制原理

    Redis lock_lock锁机制原理Redisson分布式锁原理1.工具类packagecom.meta.mall.common.utils;importlombok.extern.slf4j.Slf4j;importorg.redisson.api.RLock;importorg.redisson.api.RedissonClient;importorg.springframework.stereotype.Component;importjavax.annotation.Resource;import

    2022年10月15日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号