当前位置: 首页 > news >正文

免费做的网站怎么设置域名百度指数有三个功能模块

免费做的网站怎么设置域名,百度指数有三个功能模块,北京东道设计,在线平面设计招聘目录 环形缓冲区#xff08;Ring Buffer#xff09;简介 为什么选择环形缓冲区#xff1f; 代码解析 1. 头文件与类型定义 1.1 头文件保护符 1.2 包含必要的标准库 1.3 类型定义 2. 环形缓冲区结构体 2.1 结构体成员解释 3. 辅助宏与内联函数 3.1 min 宏 3.2 is…目录 环形缓冲区Ring Buffer简介 为什么选择环形缓冲区 代码解析 1. 头文件与类型定义 1.1 头文件保护符 1.2 包含必要的标准库 1.3 类型定义 2. 环形缓冲区结构体 2.1 结构体成员解释 3. 辅助宏与内联函数 3.1 min 宏 3.2 is_power_of_two 内联函数 3.3 roundup_power_of_two 内联函数 4. 环形缓冲区的基本操作 4.1 创建新缓冲区 4.2 获取缓冲区长度 4.3 释放缓冲区 4.4 添加数据到缓冲区 4.5 从缓冲区移除数据 4.6 清空缓冲区的一部分数据 4.7 在缓冲区中搜索特定字符串 4.8 获取写入缓冲区的可写指针 5. 其他辅助函数 5.1 判断缓冲区是否为空 5.2 判断缓冲区是否已满 5.3 获取缓冲区中剩余的空间 6. 代码中的关键概念与实现 6.1 环形地址计算 6.2 缓冲区大小为2的幂次方 6.3 双指针机制 7. 综合应用 7.1 在用户态缓存区中的应用 7.2 处理生产者与消费者速度不匹配 7.3 结合之前的内容 8. 总结 环形缓冲区Ring Buffer简介 环形缓冲区是一种高效的数据结构广泛应用于生产者-消费者模型中。在网络通信中尤其是用户态缓存区中环形缓冲区通过循环使用固定大小的内存区域减少数据移动和内存管理开销提升数据传输效率。 为什么选择环形缓冲区 减少数据移动数据在缓冲区中循环写入和读取避免了频繁的数据拷贝操作。高效缓存管理适用于高并发场景能够快速响应数据的读写请求。简化内存管理固定大小的缓冲区结构简化了内存分配和释放。 代码解析 让我们逐步解析环形缓冲区代码理解其各个部分的功能和实现细节。 1. 头文件与类型定义 #ifndef _ringbuffer_h #define _ringbuffer_h#include stdio.h #include stdlib.h #include string.h // #include limits.h // for uint_max #include stdint.h #include unistd.htypedef struct ringbuffer_s buffer_t;buffer_t * buffer_new(uint32_t sz);uint32_t buffer_len(buffer_t *r);void buffer_free(buffer_t *r);int buffer_add(buffer_t *r, const void *data, uint32_t sz);int buffer_remove(buffer_t *r, void *data, uint32_t sz);int buffer_drain(buffer_t *r, uint32_t sz);int buffer_search(buffer_t *r, const char* sep, const int seplen);uint8_t * buffer_write_atmost(buffer_t *r);#endif1.1 头文件保护符 #ifndef _ringbuffer_h #define _ringbuffer_h ... #endif作用防止头文件被多次包含避免重复定义错误。 1.2 包含必要的标准库 #include stdio.h #include stdlib.h #include string.h // #include limits.h // for uint_max #include stdint.h #include unistd.h标准库提供了内存管理malloc、free、字符串操作memcpy、固定宽度整数类型uint32_t、uint8_t等功能。 1.3 类型定义 typedef struct ringbuffer_s buffer_t;作用为 struct ringbuffer_s 定义一个别名 buffer_t简化后续代码的书写。 2. 环形缓冲区结构体 struct ringbuffer_s {uint32_t size;uint32_t tail;uint32_t head;uint8_t * buf; };2.1 结构体成员解释 size (uint32_t)缓冲区的总大小以字节为单位。通常为2的幂次方便于使用位运算实现环形效果。 tail (uint32_t)指向缓冲区的写入位置。每次添加数据时tail 会递增。 head (uint32_t)指向缓冲区的读取位置。每次移除数据时head 会递增。 buf (uint8_t *)指向实际数据存储区的指针。数据以字节形式存储。 3. 辅助宏与内联函数 #define min(lth, rth) ((lth)(rth)?(lth):(rth))static inline int is_power_of_two(uint32_t num) {if (num 2) return 0;return (num (num - 1)) 0; }static inline uint32_t roundup_power_of_two(uint32_t num) {if (num 0) return 2;int i 0;for (; num ! 0; i)num 1;return 1U i; }3.1 min 宏 #define min(lth, rth) ((lth)(rth)?(lth):(rth))作用返回两个值中的较小者简化代码中的条件判断。 3.2 is_power_of_two 内联函数 static inline int is_power_of_two(uint32_t num) {if (num 2) return 0;return (num (num - 1)) 0; }作用判断一个数是否为2的幂次方。原理2的幂次方数在二进制中只有一个1其减1后所有位都会变为1按位与结果为0。 3.3 roundup_power_of_two 内联函数 static inline uint32_t roundup_power_of_two(uint32_t num) {if (num 0) return 2;int i 0;for (; num ! 0; i)num 1;return 1U i; }作用将一个数向上舍入到最近的2的幂次方。实现通过不断右移操作计算出需要的位数然后使用位移生成对应的2的幂次方数。 4. 环形缓冲区的基本操作 4.1 创建新缓冲区 buffer_t * buffer_new(uint32_t sz) {if (!is_power_of_two(sz)) sz roundup_power_of_two(sz);buffer_t * buf (buffer_t *)malloc(sizeof(buffer_t) sz);if (!buf) {return NULL;}buf-size sz;buf-head buf-tail 0;buf-buf (uint8_t *)(buf 1);return buf; }功能分配并初始化一个新的环形缓冲区。步骤 检查传入的大小 sz 是否为2的幂次方。如果不是则向上舍入到最近的2的幂次方数。分配内存sizeof(buffer_t) sz。buffer_t结构体和实际数据存储区 buf 一起分配。初始化结构体成员 size设置为调整后的大小 sz。head 和 tail初始化为0表示缓冲区为空。buf指向结构体之后的内存区域即实际的数据存储区。 4.2 获取缓冲区长度 uint32_t buffer_len(buffer_t *r) {return rb_len(r); }static uint32_t rb_len(buffer_t *r) {return r-tail - r-head; }功能返回缓冲区中当前存储的数据长度。实现通过 tail - head 计算当前缓冲区中有效数据的字节数。 4.3 释放缓冲区 void buffer_free(buffer_t *r) {free(r);r NULL; }功能释放之前分配的缓冲区内存。注意设置指针为 NULL 只是为了防止悬挂指针但在函数外部无效。 4.4 添加数据到缓冲区 int buffer_add(buffer_t *r, const void *data, uint32_t sz) {if (sz rb_remain(r)) {return -1;}uint32_t i;i min(sz, r-size - (r-tail (r-size - 1)));memcpy(r-buf (r-tail (r-size - 1)), data, i);memcpy(r-buf, datai, sz-i);r-tail sz;return 0; }static uint32_t rb_remain(buffer_t *r) {return r-size - r-tail r-head; }功能将数据添加到缓冲区中。步骤 检查剩余空间 使用 rb_remain(r) 计算缓冲区中剩余的可用空间。如果要添加的数据大小 sz 超过剩余空间返回错误 -1。计算可写入的字节数 i 使用 min(sz, r-size - (r-tail (r-size - 1))) 计算可以连续写入的最大字节数避免跨越缓冲区末尾。数据拷贝 第一部分将前 i 字节的数据拷贝到缓冲区当前位置。第二部分如果有剩余的数据sz - i将其从缓冲区的起始位置开始拷贝形成环形。更新 tail将 tail 指针增加 sz标记新数据的结束位置。返回成功返回 0 表示数据添加成功。 4.5 从缓冲区移除数据 int buffer_remove(buffer_t *r, void *data, uint32_t sz) {assert(!rb_isempty(r));uint32_t i;sz min(sz, r-tail - r-head);i min(sz, r-size - (r-head (r-size - 1)));memcpy(data, r-buf(r-head (r-size - 1)), i);memcpy(datai, r-buf, sz-i);r-head sz;return sz; }static uint32_t rb_isempty(buffer_t *r) {return r-head r-tail; }功能从缓冲区中移除并读取数据。步骤 断言缓冲区不为空使用 assert(!rb_isempty(r)) 确保缓冲区中有数据可读。调整读取大小将 sz 限制为缓冲区中实际存储的数据量 r-tail - r-head。计算可连续读取的字节数 i 使用 min(sz, r-size - (r-head (r-size - 1))) 计算可以连续读取的最大字节数避免跨越缓冲区末尾。数据拷贝 第一部分将前 i 字节的数据从缓冲区当前位置拷贝到目标缓冲区。第二部分如果有剩余的数据sz - i将其从缓冲区的起始位置开始拷贝。更新 head将 head 指针增加 sz标记数据的读取位置。返回读取的字节数返回实际读取的数据大小 sz。 4.6 清空缓冲区的一部分数据 int buffer_drain(buffer_t *r, uint32_t sz) {if (sz rb_len(r))sz rb_len(r);r-head sz;return sz; }功能从缓冲区中清除 sz 字节的数据而不读取到用户空间。步骤 调整清除大小将 sz 限制为缓冲区中实际存储的数据量 rb_len(r)。更新 head将 head 指针增加 sz标记数据的清除位置。返回清除的字节数返回实际清除的数据大小 sz。 4.7 在缓冲区中搜索特定字符串 int buffer_search(buffer_t *r, const char* sep, const int seplen) {int i;for (i 0; i rb_len(r)-seplen; i) {int pos (r-head i) (r-size - 1);if (pos seplen r-size) {if (memcmp(r-bufpos, sep, r-size-pos))return 0;if (memcmp(r-buf, sepr-size-pos, posseplen-r-size) 0) {return iseplen;}}if (memcmp(r-bufpos, sep, seplen) 0) {return iseplen;}}return 0; }功能在缓冲区中搜索特定的分隔符 sep用于界定数据包的边界如协议解析。步骤 遍历缓冲区从 head 开始逐个字节检查是否匹配 sep。计算当前检查的位置 pos使用 (r-head i) (r-size - 1) 实现环形地址计算。处理跨越缓冲区末尾的情况 如果 pos seplen r-size表示分隔符跨越缓冲区末尾需要分两部分比较。第一部分比较从 pos 到缓冲区末尾的部分。第二部分比较从缓冲区起始位置到剩余长度的部分。匹配成功如果找到匹配的分隔符返回分隔符的位置偏移量 i seplen。未找到匹配返回 0表示未找到。 4.8 获取写入缓冲区的可写指针 uint8_t * buffer_write_atmost(buffer_t *r) {uint32_t rpos r-head (r-size - 1);uint32_t wpos r-tail (r-size - 1);if (wpos rpos) {uint8_t* temp (uint8_t *)malloc(r-size * sizeof(uint8_t));memcpy(temp, r-bufrpos, r-size - rpos);memcpy(tempr-size-rpos, r-buf, wpos);free(r-buf);r-buf temp;return r-buf;}return r-buf rpos; }功能获取当前缓冲区中可写入数据的位置指针最多可写入的字节数。步骤 计算读取和写入位置 rposhead 指针在缓冲区中的当前位置。wpostail 指针在缓冲区中的当前位置。判断是否需要重新排列缓冲区 如果 wpos rpos表示写入位置已环绕到缓冲区的起始位置需要将数据重新排列使得写入位置连续。重新排列 分配新的缓冲区 temp大小与原缓冲区相同。将从 rpos 到缓冲区末尾的数据复制到 temp 的起始位置。将从缓冲区起始位置到 wpos 的数据复制到 temp 的剩余位置。释放原缓冲区内存并将 buf 指针指向新的缓冲区 temp。返回新的缓冲区起始位置。直接返回写入位置 如果不需要重新排列直接返回 buf rpos即当前可写入的位置。 5. 其他辅助函数 5.1 判断缓冲区是否为空 static uint32_t rb_isempty(buffer_t *r) {return r-head r-tail; }功能检查缓冲区是否为空。返回值1 表示为空0 表示不为空。 5.2 判断缓冲区是否已满 static uint32_t rb_isfull(buffer_t *r) {return r-size (r-tail - r-head); }功能检查缓冲区是否已满。返回值1 表示已满0 表示未满。 5.3 获取缓冲区中剩余的空间 static uint32_t rb_remain(buffer_t *r) {return r-size - r-tail r-head; }功能计算缓冲区中剩余的可用空间。返回值剩余空间的字节数。 6. 代码中的关键概念与实现 6.1 环形地址计算 在环形缓冲区中head 和 tail 指针是以字节为单位递增的。当指针超过缓冲区的大小时通过位运算 (r-size - 1)将其映射回缓冲区的起始位置实现环形效果。 (r-tail (r-size - 1))条件r-size 通常为2的幂次方这样 (r-size - 1) 就是一个全1的二进制数可以用来快速计算模运算。 6.2 缓冲区大小为2的幂次方 为了简化环形地址的计算缓冲区的大小通常设置为2的幂次方。这不仅提高了效率还使得位运算成为可能从而加快了数据的读写操作。 6.3 双指针机制 head指向下一个读取位置。tail指向下一个写入位置。优势通过维护两个指针可以高效地管理生产者写入和消费者读取之间的数据流动避免数据冲突和竞争条件。 7. 综合应用 7.1 在用户态缓存区中的应用 在用户态缓存区中环形缓冲区用于存储和管理网络数据的读写操作。生产者如内核协议栈将数据添加到缓冲区消费者如应用程序从缓冲区读取数据。通过环形缓冲区的高效管理确保数据传输的流畅性和可靠性。 7.2 处理生产者与消费者速度不匹配 当生产者如内核协议栈生成数据的速度快于消费者应用程序的处理速度时缓冲区可以暂存这些数据避免数据丢失。同样当消费者处理数据的速度快于生产者生成数据的速度时缓冲区也能有效地管理数据流动确保数据的连续性。 7.3 结合之前的内容 用户态缓存高效数据交互与性能优化https://blog.csdn.net/weixin_43925427/article/details/142354725?fromshareblogdetailsharetypeblogdetailsharerId142354725sharereferPCsharesourceweixin_43925427sharefromfrom_link在之前的讲解中我们提到了读写缓存区在网络通信中的重要性以及不同的缓冲区设计固定内存块、环形缓冲区、链式缓冲区对性能和效率的影响。环形缓冲区通过减少数据移动和优化内存管理提升了数据传输的效率和系统的整体性能。 8. 总结 通过详细解析这段环形缓冲区的代码我们深入理解了环形缓冲区的结构和工作原理 高效的数据管理通过固定大小的缓冲区和双指针机制环形缓冲区实现了高效的数据读写操作。减少数据移动利用环形地址计算和分段拷贝避免了大量的数据拷贝和移动操作提升了性能。灵活的空间管理通过动态调整和优化如 buffer_write_atmost 函数环形缓冲区能够适应不同的数据量需求保持高效运行。可靠的数据传输在生产者和消费者速度不匹配的情况下环形缓冲区通过暂存和管理数据确保数据的完整性和可靠性。 参考 0voice · GitHub GitHub - TryTryTL/buffer_design 用户态缓存高效数据交互与性能优化-CSDN博客
http://www.eeditor.cn/news/126090/

相关文章:

  • 设计公司网站需要考虑什么临沂网站临沂网站制作
  • 网站建设人员培训用html做的网站加背景音乐
  • 会计网站模板湖州做网站优化
  • 二级域名做网址导航大全网站温州好的网站推广
  • 企业网站建立的失败案例网站欢迎页代码
  • cms大型门户网站 源码网页设计实训报告任务书
  • 甘肃手机版建站系统价格营销网站开发系统
  • 如何做网站词库江苏省建筑网监督信息平台
  • 打开网站弹出qq网站子站建设
  • 张店低价网站建设网站如何选择服务器
  • 为什么备案关闭网站网站开发报价表格
  • 网站开发通用流程图代做网站推广的公司
  • 中国建设局网站临海市住房与城乡建设规划局网站
  • 用.net做网站好 还是用php网站建设的相关新闻
  • 有教做点心的网站吗莆田网站自助建站
  • 网站建设分工明细表宁波网站制作首荐荣盛网络好
  • 做暧暧视频免费视频网站海沧区建设局网站市政处
  • 网站流量超昌吉网站建设电话
  • wordpress视频页面沙洋县seo优化排名价格
  • 给人做网站做一个15页的网站怎么做
  • 太原工程建设信息网站百度seo怎么收费
  • 用什么软件来做网站山东网站建设模板制作
  • 电子商务网站建设与管理期末考试网站建设高校
  • 做网站建设公司企业物联网设计论文
  • 电子商务网站模块免费ppt模板下载网址不需要会员
  • 石家庄网站推广专业濮阳市建设工程交易网
  • 网站列表页是啥浙江大成建设集团有限公司网站
  • 黄页网站介绍制作网站建网站
  • 网站域名必须备案吗怎么把网站放到服务器上
  • 响应式网站建设推荐乐云践新金方时代网站建设