循环缓冲区(RingBuffer)
1、循环缓冲区的实现原理
环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。
2、概念
中文名是环形缓冲区,也被叫做循环缓冲区。关于循环缓冲区(RingBuffer)的概念,其实来自于Linux内核(Maybe),是为解决某些特殊情况下的竞争问题提供了一种免锁的方法。这种特殊的情况就是当生产者和消费者都只有一个,而在其它情况下使用它也是必须要加锁的。对应在Linux内核中有对它的定义:
struct kfifo {
unsigned char *buffer;
unsigned int size;
unsigned int in;
unsigned int out;
spinlock_t *lock;
};其中buffer指向存放数据的缓冲区,size是缓冲区的大小,in是写指针下标,out是读指针下标,lock是加到struct kfifo上的自旋锁(上面说不加锁不是这里的锁),防止多个进程并发访问此数据结构。当in==out时,说明缓冲区为空;当(in-out)==size时,说明缓冲区已满。
RingBuffer,也就是环形缓冲区,是一种在多线程编程场景中极为常用的数据结构。它就像一个首尾相接的环形轨道,数据的写入和读取在这个环形轨道上循环进行。这种结构在处理生产者 - 消费者模型时,有着独特的优势。想象一下,在一个数据处理系统中,有多个线程不断地产生数据(生产者),同时又有其他线程需要持续地处理这些数据(消费者),RingBuffer 就能够很好地在两者之间起到缓冲和协调的作用。
而线程安全则是在多线程环境下必须要重点考虑的因素。多个线程同时对 RingBuffer 进行读写操作时,如果没有合理的机制来保证数据的一致性和操作的原子性,就会出现诸如数据竞争、脏读、写覆盖等严重问题。
3、
在涉及到模块与模块间数据传输缓存处理、通信程序中,经常使用环形缓冲区(Ring Buffer)作为数据结构来存放通信中发送和接收的数据。
https://mp.weixin.qq.com/s/apD2gAsrgguJT_uPMPSf7A demo见:D:\interview\Storage\c++\study\advanced\RingBuffer\ringbuffer.c