前不久,因爲項目的要求對數據存取十分頻繁,如果每次都是分配內存,然後釋放,會產生大量的內存碎片,所以設計了一個數據池模板類,該類很簡單,主要功能有:
1. 初始化數據池
2. 清空數據池
3. 取得一段數據緩衝區
4. 釋放一段數據緩衝區
5. 取得緩衝區記錄數
如何使用:
使用步驟如下:
1, 創建數據池:
CDataBuffer<MyStruct> Databuf;
Databuf.Init();
2, 如果你需要設置數據池的大小,可以調用SetMaxBufSize函數來完成,函數定義如下:
bool SetMaxBufSize(long lMaxBufSize); lMaxBufSize是要指定的數據池大小。
Databuf. SetMaxBufSize(10*1024*1024);//大小設爲10M
3, 當你想取得一條記錄時:
MyStruct * pData = Databuf.GetBuffer();
4, 在使用完該記錄後:
Databuf. ReleaseBuffer(pData);
夠簡單的吧,好了,下面時程序的代碼:
#if !defined(AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_)
#define AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <list>
#include "MutexLock.h"
using namespace std;
//最大數據池容量 單位是BYTE
#define MAXBUFFERSIZE 10*1024*1024
template <class TData>
class CDataBuffer
{
public:
CDataBuffer()
{
//默認數據池容量爲10M
m_lMaxBufferCount = MAXBUFFERSIZE/sizeof(TData);
}
virtual ~CDataBuffer(){Close();}
//取得一個數據緩衝區
TData * GetBuffer();
//釋放數據緩衝區,這裏沒有真正釋放,而是把數據存放到數據池中
bool ReleaseBuffer(TData * pData)
{
//先把數據緩衝清零
memset(pData, 0x00, sizeof(TData));
m_pMutex->Lock(1000);
if(m_lDataPool.size() >= m_lMaxBufferCount)
{//如果數據池已經滿了, 只好把該緩衝區釋放.
try
{
delete pData;
pData = NULL;
}
catch (...)
{
}
}
else
{
//數據池沒有滿,添加到數據池
m_lDataPool.push_back(pData);
}
m_pMutex->UnLock();
return true;
}
//取得數據池中有多少數據緩衝區
long GetBufferCount()
{
long lRet = 0;
m_pMutex->Lock(1000);
lRet = (long)m_lDataPool.size();
m_pMutex->UnLock();
return lRet;
}
//設置數據池允許的最大數據容量
bool SetMaxBufSize(long lMaxBufSize)
{
if(lMaxBufSize > 1024)
{
m_lMaxBufferCount = lMaxBufSize/sizeof(TData);
return true;
}
return false;
}
//取得數據池允許的最大數據容量
long GetMaxBufSize()
{
return m_lMaxBufferCount*sizeof(TData);
}
//初始化
bool Init();
//清空緩衝區
bool ClearBufferPool();
//
private:
//關閉
bool Close()
{
//清空數據池
ClearBufferPool();
//釋放互斥區
if(m_pMutex != NULL)
{
delete m_pMutex;
m_pMutex = NULL;
}
return true;
}
private:
typedef list<TData* > BUFFER_LIST;
BUFFER_LIST m_lDataPool; //數據池
CMutexLock* m_pMutex; //互斥區
long m_lMaxBufferCount; //最大數據緩衝區數
};
//////////////////////////////////////////////////////////////////////////
template <class TData>
bool CDataBuffer<TData>::Init()
{
//創建緩衝區
m_pMutex = new CWinMutex;
if(m_pMutex == NULL)
{
return false;
}
return true;
}
template <class TData>
bool CDataBuffer<TData>::ClearBufferPool()
{
BUFFER_LIST::iterator first = m_lDataPool.begin();
BUFFER_LIST::iterator last = m_lDataPool.end();
TData * pData= NULL;
try
{
//輪詢釋放
while (first != last)
{
pData = (TData*)*first;
if(pData != NULL)
{
delete pData;
pData = NULL;
}
first++;
}
//清空列表
m_lDataPool.clear();
}
catch (...)
{
return false;
}
return true;
}
template <class TData>
TData* CDataBuffer<TData>::GetBuffer()
{
TData * pData = NULL;
m_pMutex->Lock(1000);
if(m_lDataPool.size() > 0)
{
//如果數據池中有空餘的數據緩衝區,取出來
pData = (TData*)m_lDataPool.front();
//從數據池中刪除
m_lDataPool.pop_front();
}
m_pMutex->UnLock();
if(pData == NULL)
{//沒有找到空餘數據,只好創建一個
pData = new TData;
}
//注意,如果內存耗盡,系統快崩潰時,這裏取得的也是NULL指針
return pData;
}
//////////////////////////////////////////////////////////////////////////
#endif // !defined(AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_)