前言
环形缓冲区是嵌入式常用的数据结构,该数据结构内存大小固定,通常采用定长数组来管理数据,在写入时,如果缓冲区满了,则重新从头开始写入。
CMake配置
cmake_minimum_required(VERSION 3.5.1)
project(ringbuf)
add_executable(ringbuf ringbuf.cpp)
set(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_CXX_FLAGS "--std=c++11")
全部代码
通过模板,分配一个固定大小的内存缓冲,然后循环设置、读取
#include <iostream>
template<class T, size_t N>
class RingBuffer {
private:
T objects[N];
size_t read;
size_t write;
size_t queued;
public:
RingBuffer(): read(0), write(0), queued(0) {}
T& push() {
T& current = objects[write];
write = (write + 1) % N;
queued++;
if (queued > N) {
queued = N;
read = write;
}
return current;
}
const T& pull() {
if (!queued) {
throw std::runtime_error("No data in the ring buffer");
}
T& current = objects[read];
read = (read + 1) % N;
queued--;
return current;
}
bool has_data() {
return queued != 0;
}
};
struct Frame {
uint32_t index;
uint8_t data[1024];
};
int main() {
RingBuffer<Frame, 10> frames;
std::cout << "Frames " << (frames.has_data() ? "" : "do not ")
<< "contain data" << std::endl;
try {
const Frame& frame = frames.pull();
} catch (std::runtime_error e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
for (size_t i = 0; i < 5; i++) {
Frame& out = frames.push();
out.index = i;
out.data[0] = 'a' + i;
out.data[1] = '\0';
}
std::cout << "Frames " << (frames.has_data() ? "" : "do not ")
<< "contain data" << std::endl;
while (frames.has_data()) {
const Frame& in = frames.pull();
std::cout << "Frame " << in.index << ": " << in.data << std::endl;
}
for (size_t i = 0; i < 26; i++) {
Frame& out = frames.push();
out.index = i;
out.data[0] = 'a' + i;
out.data[1] = '\0';
}
std::cout << "Frames " << (frames.has_data() ? "" : "do not ")
<< "contain data" << std::endl;
while (frames.has_data()) {
const Frame& in = frames.pull();
std::cout << "Frame " << in.index << ": " << in.data << std::endl;
}
}
实验结果
我公司承接各类技术服务,主要聚焦于:stm32、单片机、嵌入式、QT应用开发、Web+Python+Django应用开发。欢迎合作。