物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区

随着5G的普及,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,采用epoll模式支持IoT数十万的高并发连接,并且兼容ModSecurity部分规则。 代码非常优秀,非常值得收藏和学习,今天笔者就从结合himqtt的源码来进行ringbuffer数据结构分析,主要特点是速度快。

一、 ringBuffer 介绍

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

、 ringBuffer 优点

1、Ring Buffer 比链表要快,因为它是数组,而且有一个容易预测的访问模式。这很不错,对 CPU 高速缓存友好 (CPU-cache-friendly)-数据可以在硬件层面预加载到高速缓存,因此 CPU 不需要经常回到主内存 RAM 里去寻找 Ring Buffer 的下一条数据。

2、Ring Buffer 是一个数组,你可以预先分配内存,并保持数组元素永远有效。这意味着内存垃圾收集(GC)在这种情况下几乎什么也不用做。此外,也不像链表那样每增加一条数据都要创建对象-当这些数据从链表里删除时,这些对象都要被清理掉。

总之就是内存处理速度特别快,特别适合高并发、大量的请求。

三、ringBuffer 代码实现

首先在github上下载himqtt的源码:https://github.com/qq4108863/himqtt

找到src目录下的ringbuffer.c和ringbuffer.h文件。

1、ringBuffer 的结构体

typedef struct bufent {

char *data;

char *ptr;

size_t left;

struct bufent *next;

} bufent;

typedef struct ringbuffer {

bufent *slots;

bufent *head; // reads from the head

bufent *tail; // writes to the tail

char   *buf;

int used;

int num_slots;

int data_len;

size_t bytes_written;

} ringbuffer;

2、创建 ringBuffer 函数

void

ringbuffer_init(ringbuffer *rb, int num_slots, int data_len)

{

rb->num_slots = num_slots ?: DEF_RING_SLOTS;

rb->data_len = data_len ?: DEF_RING_DATA_LEN;

rb->slots = malloc(rb->num_slots * sizeof(rb->slots[0]));

AN(rb->slots);

rb->head = &rb->slots[0];

rb->tail = &rb->slots[0];

int x;

for (x=0; x < rb->num_slots; x++) {

rb->slots[x].next = &(rb->slots[(x + 1) % rb->num_slots]);

rb->slots[x].data = malloc(rb->data_len);

AN(rb->slots[x].data);

}

rb->used = 0;

rb->bytes_written = 0;

}

3、清空 ringBuffer 函数

void

ringbuffer_cleanup(ringbuffer *rb)

{

int x;

for (x=0; x < rb->num_slots; x++) {

free(rb->slots[x].data);

}

free(rb->slots);

}

4、读数据函数

char *

ringbuffer_read_next(ringbuffer *rb, int * length)

{

assert(rb->used);

*length = rb->head->left;

return rb->head->ptr;

}

5、写数据函数

void

ringbuffer_write_append(ringbuffer *rb, int length)

{

assert(rb->used < rb->num_slots);

rb->used++;

rb->tail->ptr = rb->tail->data;

rb->tail->left = length;

rb->tail = rb->tail->next;

}

如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。

Ringbuffer特别适合一个读,一个写的高速场景。5G 时代就是大量的设备会联网,并且持续通信,对himqtt这类物联网防火墙就提出了很高的要求,所以算法和数据结构设计就非常重要。

物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区的更多相关文章

  1. 物联网安全himqtt防火墙数据结构之红黑树源码分析

    物联网安全himqtt防火墙数据结构之红黑树源码分析 随着5G的发展,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWa ...

  2. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮. 嵌入式框架Zorb Framework搭建过程 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建.调试输出和建立时间系 ...

  3. 环形缓冲区的应用ringbuffer

    在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法, 当读取速度大于写入速度时,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外). 在通信程序中,经常使用环形缓冲区作为数 ...

  4. C#环形缓冲区(队列)完全实现

    公司项目中经常设计到串口通信,TCP通信,而且大多都是实时的大数据的传输,然后大家都知道协议通讯肯定涉及到什么,封包.拆包.粘包.校验--什么鬼的概念一大堆,说简单点儿就是要一个高效率可复用的缓存区. ...

  5. STM32进阶之串口环形缓冲区实现

    队列的概念 在此之前,我们来回顾一下队列的基本概念: 队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO)的线性表,只允许在一端插入(入队),在另一端进行删除 ...

  6. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  7. 35.Linux-分析并制作环形缓冲区

    在上章34.Linux-printk分析.使用printk调试驱动里讲述了: printk()会将打印信息存在内核的环形缓冲区log_buf[]里, 可以通过dmesg命令来查看log_buf[] 1 ...

  8. input子系统事件处理层(evdev)的环形缓冲区【转】

    在事件处理层(evdev.c)中结构体evdev_client定义了一个环形缓冲区(circular buffer),其原理是用数组的方式实现了一个先进先出的循环队列(circular queue), ...

  9. 环形缓冲区-模仿linux kfifo【转】

    转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...

随机推荐

  1. CSS3过渡动画&关键帧动画

    一.过渡动画 过渡(transition)动画,就是从初始状态过渡到结束状态这个过程中所产生的动画. 所谓的状态就是指大小.位置.颜色.变形(transform)等等这些属性. Note:不是所有属性 ...

  2. vue开发记录

    vue开发过程中遇到的一些小问题.小技巧等,会不断更新~ 记录不详细处,欢迎留言

  3. 将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy

    将pandas的DataFrame数据写入MySQL数据库 + sqlalchemy import pandas as pd from sqlalchemy import create_engine ...

  4. SIGAI机器学习第五集 贝叶斯分类器

    讲授贝叶斯公式.朴素贝叶斯分类器.正态贝叶斯分类器的原理.实现以及实际应用 大纲: 贝叶斯公式(直接用贝叶斯公式完成分类,计算一个样本的特征向量X属于每个类c的概率,这个计算是通过贝叶斯公式来完成的. ...

  5. iOS测试-如何指标量化app耗电量和性能XCTest Metrics

    对于app端的专项测试,Android端我们可以用adb或者一些三方工具进行(例如itest)进行实时的性能监控,iOS端的话也可以用用一些三方的工具,但是需要嵌入到我们的项目当中,今天来介绍下Xco ...

  6. ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc HINT:

    报错信息 ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc H ...

  7. arcgis python 随机取部分数据

    # -*- coding: cp936 -*- import arcpy import os import ylpy import random def main(): num=ylpy.getCou ...

  8. Flutter移动电商实战 --(38)路由_Fluro中Handler编写方法

    在main.dart中初始化Fluro 编写handler 在lib下新建routers文件夹,表示里面要很多路由相关的文件 我们声明一个Handler,在里面handlerFunc固定的两个参数 重 ...

  9. Vue篇之vue 使用Jade模板写html

    // 安装jade包 npm install jade jade-loader --save-dev // 如果使用vue-cli构建项目,则不需要安装stylus相关的包,vue-cli默认已安装 ...

  10. Vue生命周期钩子函数加载顺序的理解

    Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过程,就是生命周期 ...