C++简单内存池的实现

#ifndef _MEM_POOL_H
#define _MEM_POOL_H

#include <vector>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>

using std::cout;
using std::endl;

#define ASSERT(expr) \
do\
{\
    if (!(expr))\
    {\
       fprintf(stderr, "%s: %d\t(%s)\tAssertion failed\n",__FILE__, __LINE__, #expr);\
       abort();\
    }\
}while(0)

class CLock
{
public:
    CLock();
    ~CLock();
    void lock();
    void unlock();
private:
    pthread_mutex_t m_mutex;
};
    

/*
	在内存池中分配固定大小的内存块
	该类的目的是加速内存分配速度,并且减少因重复分配相同
	内存时产生的内存碎片,比如在服务器应用程序中。
*/

class CMemPool
{
public:

    //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc,maxAlloc为0表示无限制
    CMemPool(std::size_t blockSize, int preAlloc = 0, int maxAlloc = 0);

    ~CMemPool();

    //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块
    //如果分配的内存块数目达到了最大值,则会返回一个NULL,并打印内存耗尽异常
    void* Get();

    //释放当前内存块,将其插入内存池
    void Release(void* ptr);

    //返回内存块大小
    std::size_t BlockSize() const;

    //返回内存池中内存块数目
    int Allocated() const;

    //返回内存池中可用的内存块数目
    int Available() const;

private:
    CMemPool();
    CMemPool(const CMemPool&);
    CMemPool& operator = (const CMemPool&);

    enum
    {
        BLOCK_RESERVE = 32
    };

    typedef std::vector<char*> BlockVec;

    std::size_t m_blockSize;
    int         m_maxAlloc;
    int         m_allocated;
    BlockVec    m_blocks;
    CLock m_mutex;
};

inline std::size_t CMemPool::BlockSize() const
{
    return m_blockSize;
}


inline int CMemPool::Allocated() const
{
    return m_allocated;
}


inline int CMemPool::Available() const
{
    return (int) m_blocks.size();
}


#endif

#include "MemPool.h"

CLock::CLock()
{
    pthread_mutex_init(&m_mutex, NULL);
}

CLock::~CLock()
{
    
}

void CLock::lock()
{
    //cout<< "CLock try to get lock..."<<endl;
    pthread_mutex_lock(&m_mutex);
    //cout<< "CLock got lock..."<<endl;
}

void CLock::unlock()
{
    pthread_mutex_unlock(&m_mutex);
    //cout<< "CLock release lock..."<<endl;
}

CMemPool::CMemPool(std::size_t blockSize, int preAlloc, int maxAlloc):
    m_blockSize(blockSize),
    m_maxAlloc(maxAlloc),
    m_allocated(preAlloc)
{
    ASSERT(preAlloc >= 0 || maxAlloc >= 0);
    /*
    if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )
    {
        cout<<"CMemPool::CMemPool parameter error."<<endl;
    }*/

    int r = BLOCK_RESERVE;
    if (preAlloc > r)
        r = preAlloc;
    if (maxAlloc > 0 && maxAlloc < r)
        r = maxAlloc;
    m_blocks.reserve(r);
    for (int i = 0; i < preAlloc; ++i)
    {
        char *ptr = new char[m_blockSize];
        ASSERT(ptr != NULL);
        m_blocks.push_back(ptr);
    }
}


CMemPool::~CMemPool()
{
    for (BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it)
    {
        delete [] *it;
    }
}


void* CMemPool::Get()
{
    m_mutex.lock();
    char* ptr = NULL;
    
    if (m_blocks.empty())
    {
        if (m_maxAlloc == 0 || m_allocated < m_maxAlloc)
        {
            ++m_allocated;
            ptr = new char[m_blockSize];
        }
        else
        {
            cout<<"CMemPool::get CMemPool exhausted."<<endl;
        }
    }
    else
    {
        ptr = m_blocks.back();
        m_blocks.pop_back();
    }

    m_mutex.unlock();
    return ptr;
}


void CMemPool::Release(void* ptr)
{
    m_mutex.lock();   
    memset(ptr, 0, m_blockSize);
    m_blocks.push_back(reinterpret_cast<char*>(ptr));
    m_mutex.unlock(); 
}

#include "MemPool.h"

#define DATA_BLOCK_LEN 1024

int main(int argc, char* argv[])
{
    CMemPool myPool1(DATA_BLOCK_LEN, 0, 0);

    cout<<"myPool1 block size = "<<myPool1.BlockSize()<<endl;
    cout<<"myPool1 allocated block num = "<<myPool1.Allocated()<<endl;
    cout<<"myPool1 available block num = "<<myPool1.Available()<<endl<<endl;

    std::vector<void*> ptrs;
    for (int i = 0; i < 20; ++i)
    {
        void *temp = myPool1.Get();
        ASSERT(temp != NULL);
        ptrs.push_back(temp);
    }

    //void *p = myPool1.Get();
    //ASSERT(p != NULL);

    int iavilable = 0;
    for (std::vector<void*>::iterator it = ptrs.begin(); it != ptrs.end(); ++it)
    {
        myPool1.Release(*it);
        ++iavilable;
        cout<<"myPool1 available block num = "<<myPool1.Available()<<endl;
    }

    CMemPool myPool2(DATA_BLOCK_LEN, 5, 10);
    cout<<endl<<"myPool2 block size = "<<myPool2.BlockSize()<<endl;
    cout<<"myPool2 allocated block num = "<<myPool2.Allocated()<<endl;
    cout<<"myPool2 available block num = "<<myPool2.Available()<<endl;

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值