代码没贴全,就少一个锁头文件,可以做设计参考
设计思想就是维护一个空闲链表,没有用的就重新申请,有的话就拿链表的头,使用完又还给空闲链表。
/*
一个分配固定大小内存的内存池,使用链表维护
*/
#pragma once
#include <list>
using namespace std;
#include "../Thread/AutoLock.h"
using namespace Extralib::Thread;
struct Link
{
Link* m_pNext;
};
const int DEFAULT_SIZE = 100;
// T的大小不能小于4个字节
template<typename T>
class MemoryPool
{
public:
MemoryPool(); // 默认
MemoryPool(int nSize); // 内存池个数
~MemoryPool(); // 析构
T* New(); // 获得一个没有用过的内存
void Delete(T* pBuff); // 释放一个内存
void Recycle();
unsigned int GetAllCount();
unsigned int GetUsedCount();
const char* GetDesc();
private:
void Init();
void CreateMemory();// 分配内存
int m_nAll; // 所有分配的个数,统计使用
int m_nNum; // 当前使用的个数
pthread_mutex_t m_mutex; // 互斥锁
Link* m_pFree; // 空闲列表
set<char*> m_MemBlockList; // 所有分配的大的内存块,用于删除
//用于统计计数
int m_delCount;
int m_newCount;
char m_DescBuffer[256];
};
template <typename T>
MemoryPool<T>::MemoryPool()
{
Init();
}
template <typename T>
MemoryPool<T>::MemoryPool(int nSize)
{
Init();
AutoLock locker(m_mutex);
for(int i = 0; i < nSize ; ++i)
{
CreateMemory();
}
}
template<typename T>
void MemoryPool<T>::Init()
{
Debug_Assert(sizeof(T) > sizeof(char*));
pthread_mutex_init(&m_mutex,0);
m_nAll = 0;
m_nNum = 0;
m_pFree = 0;
m_delCount = 0;
m_newCount = 0;
};
template <typename T>
const char* MemoryPool<T>::GetDesc()
{
AutoLock locker(m_mutex);
sprintf(m_DescBuffer,"(All:%d,Used:%d,NewCount:%d,DelCount:%d)",m_nAll,m_nNum,m_newCount,m_delCount);
return m_DescBuffer;
}
template <typename T>
MemoryPool<T>::~MemoryPool()
{
set<char*>::iterator itor;
for(itor = m_MemBlockList.begin(); itor != m_MemBlockList.end(); ++itor)
{
delete[] (*itor);
}
m_MemBlockList.clear();
}
template< typename T>
void MemoryPool<T>::CreateMemory()
{
int nSize = 1;
// 所有分配的内存快
m_nAll += nSize;
char* pData = new char[nSize * sizeof(T)];
m_MemBlockList.insert(pData);
// 结尾连接到当前
Link* pTail = (Link*)(pData + sizeof(T) * (nSize - 1));
pTail->m_pNext = m_pFree;
// 串起来内存
m_pFree = (Link*)pData;
Link* pNode = m_pFree;
for(int i = 0; i < nSize - 1; ++i)
{
pNode->m_pNext = (Link*)(pData + (sizeof(T) * (i + 1)));
pNode = pNode->m_pNext;
}
}
template< typename T >
T* MemoryPool<T>::New()
{
AutoLock locker(m_mutex);
if( !m_pFree )
{
CreateMemory();
}
if(m_pFree)
{
m_nNum++;
m_newCount ++;
Link* pHead = m_pFree;
m_pFree = m_pFree->m_pNext;
new(pHead)T; //调用对象的构造函数
return (T*)pHead;
}
return 0;
}
template<typename T>
void MemoryPool<T>::Delete(T* pBuff)
{
AutoLock locker(m_mutex);
m_nNum--;
m_delCount ++;
pBuff->~T();
Link* pLink = (Link*)pBuff;
pLink->m_pNext = m_pFree;
m_pFree = pLink;
}
template<typename T>
void MemoryPool<T>::Recycle()
{
AutoLock locker(m_mutex);
while(m_pFree)
{
Link* pHead = m_pFree;
m_pFree = m_pFree->m_pNext;
m_MemBlockList.erase((char*)pHead);
m_nAll--;
}
}
template<typename T>
unsigned int MemoryPool<T>::GetAllCount()
{
AutoLock locker(m_mutex);
return m_nAll;
}
template<typename T>
unsigned int MemoryPool<T>::GetUsedCount()
{
AutoLock locker(m_mutex);
return m_nNum;
}