c++循环缓冲区
循环缓冲区(Circular Buffer),也称为环形缓冲区,是一种数据结构,主要用于在固定大小的缓冲区实现对数据的循环读写。这种结构允许我们在缓冲区末尾写入数据的同时,从缓冲区的开头读取数据,实现一种“环形”的效果。这种特性在某些应用场景中非常有用,以下是循环缓冲区的一些主要作用:
-
数据流的缓冲:循环缓冲区常用于处理数据流,尤其是在生产者-消费者模型中。生产者可以连续写入数据,而消费者可以以不同的速率读取数据。即使生产者和消费者的速率不一致,缓冲区仍然能够有效管理数据传输。
-
资源节约:由于缓冲区的大小是固定的,循环缓冲区节省了内存资源。它不会因为数据的动态增长而不断申请新的内存空间。
-
实时数据处理:在实时系统中,循环缓冲区可以用于处理实时数据流,比如音频或视频流。这种结构允许系统处理新数据的同时,丢弃旧数据,以确保实时性。
-
无锁并发:在某些实现中,循环缓冲区可以支持无锁(lock-free)并发读写操作。这对于需要高性能的数据传输场景非常有用,因为它减少了线程间竞争和上下文切换的开销。
-
简化数据管理:循环缓冲区简化了对缓冲区的管理,无需担心数据溢出或连续内存分配的问题。它通过简单的指针运算来管理数据的读写位置。
总之,循环缓冲区是一种高效且简单的解决方案,适用于需要连续数据输入输出的场景。
c++循环缓冲区代码
#include <windows.h>
//循环缓冲区
struct CircularBuffer{
private:
BYTE* pBuf; // 缓冲区数据
long writePos; // 往循环缓冲区写数据的位置
long readPos; // 往循环缓冲区读数据的位置
long saveSize; // 循环缓冲区剩余有效数据长度
bool isFull; // 默认0 如果往循环缓冲区写数据存满,从头继续存储时置为1。 如果读数据读到循环缓冲区尾部,从头开读时置0
CRITICAL_SECTION mutex;
long maxSize;
public:
CircularBuffer(long size)
{
maxSize = size;
pBuf = new BYTE[size] ();
InitializeCriticalSection(&mutex);
reset();
}
void reset(){
writePos = 0;
readPos = 0;
saveSize = 0;
isFull = false;
memset( pBuf, 0, maxSize);
}
bool writeData(BYTE* data,int len){
if(saveSize + len > maxSize)
return false;
if(writePos + len <= maxSize){
EnterCriticalSection(&mutex);
memcpy(pBuf + writePos,data,len);
writePos += len;
saveSize += len;
LeaveCriticalSection(&mutex);
} else {
EnterCriticalSection(&mutex);
isFull = true;
memcpy(pBuf + writePos,data,maxSize-writePos);
memcpy(pBuf,data + maxSize-writePos,len + writePos - maxSize);
writePos = len + writePos - maxSize;
saveSize += len;
LeaveCriticalSection(&mutex);
}
return true;
}
bool readData(BYTE* data,long len)
{
if(saveSize < len)
return false;
if(maxSize-readPos > len){
EnterCriticalSection(&mutex);
memcpy(data,pBuf+readPos,len);
LeaveCriticalSection(&mutex);
readPos += len;
saveSize -= len;
return true;
} else{
EnterCriticalSection(&mutex);
memcpy(data,pBuf+readPos,maxSize-readPos);
memcpy(data + maxSize-readPos,pBuf,len - maxSize + readPos);
readPos = len - maxSize + readPos;
saveSize -= len;
isFull = false;
LeaveCriticalSection(&mutex);
return true;
}
return false;
}
};
调用循环缓冲区
int main(int argc, char *argv[])
{
int size = 1024;
m_buffer = new CircularBuffer(size);
//往缓冲区里写数据
uint writeNum = 0;
if(!m_buffer->writeData((BYTE*)&writeNum,4))
g_window->logInfo("写入失败");
else
writeNum++;
//往缓冲区里读取数据
BYTE num[4];
if(m_buffer->readData(num,4))
{
uint cur = 0;
memcpy(&cur,num,4);
}else{
g_window->logInfo("读取失败");
}
return 0;
}