环形缓冲区
- 什么是环形缓冲区
环形缓冲区用于表示一个固定尺寸、头尾相连的缓冲区,通常用于缓存数据。环形缓冲区的主要特点是最大缓存数据量是固定的,当缓冲区满之后,会自动删除头部数据。
- 应用场景
总的来说,只要是固定长度的数据缓存,都可以使用环形缓冲区。个人用的较多的地方主要是视频缓存。
环形缓冲区代码示例
#include <mutex>;
#include <iostream>;
using namespace std;
template<typename T>
class RingBuffer
{
public:
RingBuffer(int iMaxBufferSize):
m_MaxBufSize(iMaxBufferSize),
m_Buffer(NULL),
m_CopyBuffer(NULL)
{
_ASSERTE(m_MaxBufSize > 0);
this->m_Buffer = new T[m_MaxBufSize];
_ASSERT(this->m_Buffer != NULL);
this->m_CopyBuffer = new T[m_MaxBufSize];
_ASSERT(this->m_CopyBuffer != NULL);
}
~RingBuffer()
{
this->m_mtElement.lock();
if (m_Buffer != NULL)
{
if (m_MaxBufSize>1)
{
delete[] m_Buffer;
delete[] m_CopyBuffer;
}
else if (1==m_MaxBufSize)
{
delete m_Buffer;
delete m_CopyBuffer;
}
m_Buffer = NULL;
m_CopyBuffer = NULL;
}
this->m_mtElement.unlock();
}
bool Append(const T element)
{
bool bRet = true;
this->m_mtElement.lock();
if (this->m_CurElementNum<=(this->m_MaxBufSize-1))
{
this->m_CurElementNum++;
this->m_Buffer[this->m_CurElementNum - 1] = element;
}
else
{
memcpy(this->m_CopyBuffer, &(this->m_Buffer[1]), (this->m_CurElementNum - 1) * sizeof(T));
this->m_CopyBuffer[this->m_CurElementNum - 1] = element;
memcpy(this->m_Buffer, this->m_CopyBuffer, this->m_CurElementNum * sizeof(T));
}
this->m_mtElement.unlock();
return bRet;
}
bool Print()
{
bool bRet = true;
this->m_mtElement.lock();
cout << "环形缓冲区结果如下:" << endl;
for (int i = 0; i < this->m_CurElementNum; i++)
{
cout << " "<<this->m_Buffer[i] << endl;
}
cout << endl;
this->m_mtElement.unlock();
return bRet;
}
bool Contains(const T element)
{
bool bRet = false;
this->m_mtElement.lock();
for (int i = 0; i < this->m_CurElementNum; i++)
{
if (element==this->m_Buffer[i])
{
bRet = true;
break;
}
}
this->m_mtElement.unlock();
return bRet;
}
T& operator[](int index)
{
T ret;
this->m_mtElement.lock();
_ASSERTE(index <= this->m_CurElementNum - 1);
ret = this->m_Buffer[index];
this->m_mtElement.unlock();
return ret;
}
private:
int m_MaxBufSize;
int m_CurElementNum;
T* m_Buffer;
T* m_CopyBuffer;
mutex m_mtElement;
};
int main()
{
RingBuffer<int>* pTempRingBuffer = new RingBuffer<int>(100);
if (pTempRingBuffer!=NULL)
{
for (int i = 0; i < 100; i++)
{
pTempRingBuffer->Append(i);
}
for (int i = 0; i < 10; i++)
{
cout << (*pTempRingBuffer)[i] << endl;
}
pTempRingBuffer->Print();
delete pTempRingBuffer;
}
getchar();
return 0;
}
- 相关说明
该类编译环境为VS2015,可以正常编译通过
该类支持多线程操作,为了保证多线程的安全性,使用MUTEX互斥锁,如果是早期开发环境,也可以改为临界区
为了降低移植难度,没有使用容器类,直接通过动态数组来存储缓存数据
在插入数据时,为了减少频繁的数据移动,采用了一个备份数组来交换数据
- 测试平台
测试平台:操作系统:Windows7
CPU: i5 6400 2.70GHZ
内存: 8G
- 性能指标
当缓冲区长度为100,单线程的插入性能如下:
插入一亿个int数据的耗时:7950ms
插入单个int数据耗时:0.0000795ms。