C++单线程线程池和多线程线程池的实现

在高效C++编程中看到一个不错的内存池实现方案,与大家共享:

(一)单线程内存池代码实现如下:
template<typename T>
class CMemoryPool
{
    public:
        enum { EXPANSION_SIZE = 32};

       CMemoryPool(unsigned int nItemCount = EXPANSION_SIZE)
        {
           ExpandFreeList(nItemCount);
        }
       
        ~CMemoryPool()
        {
            //free allmemory in the list
           CMemoryPool<T>* pNext = NULL;
            for(pNext =m_pFreeList; pNext != NULL; pNext = m_pFreeList)
            {
               m_pFreeList = m_pFreeList->m_pFreeList;
               delete [](char*)pNext;
            }
        }

       void* Alloc(unsigned int /*size*/)
        {
           if(m_pFreeList == NULL)
            {
               ExpandFreeList();
            }
           
            //get freememory from head
           CMemoryPool<T>* pHead = m_pFreeList;
            m_pFreeList= m_pFreeList->m_pFreeList;
            returnpHead;
        }

       void Free(void* p)
        {
            //push thefree memory back to list
           CMemoryPool<T>* pHead = static_cast<CMemoryPool<T>*>(p);
           pHead->m_pFreeList = m_pFreeList;
            m_pFreeList= pHead;
        }

    protected:
        //allocate memory and push to thelist
        void ExpandFreeList(unsignednItemCount = EXPANSION_SIZE)
        {
            unsigned intnSize = sizeof(T) > sizeof(CMemoryPool<T>*) ? sizeof(T) :sizeof(CMemoryPool<T>*);
           CMemoryPool<T>* pLastItem =static_cast<CMemoryPool<T>*>(static_cast<void*>(newchar[nSize]));
            m_pFreeList= pLastItem;
            for(int i=0;i<nItemCount-1; ++i)
            {
               pLastItem->m_pFreeList = static_cast<CMemoryPool<T>*>(static_cast<void*>(newchar[nSize]));
               pLastItem = pLastItem->m_pFreeList;
            }

           pLastItem->m_pFreeList = NULL;
        }

    private:
        CMemoryPool<T>* m_pFreeList;
};

它的实现思想就是每次从List的头上取内存,如果取不到则重新分配一定数量; 用完后把内存放回List头部,这样的话效率很高,因为每次List上可以取到的话,肯定是空闲的内存。

当然上面的代码只是针对单线程的,要支持多线程的话也很简单,外面加一层就可以了
(二)多线程内存池代码实现如下:
class CCriticalSection
{
public:
    CCriticalSection()
    {
       InitializeCriticalSection(&m_cs);
    }

    ~CCriticalSection()
    {
        DeleteCriticalSection(&m_cs);
    }

    voidLock()
    {
        EnterCriticalSection(&m_cs);
    }

    voidUnlock()
    {
        LeaveCriticalSection(&m_cs);
    }

protected:
    CRITICAL_SECTION m_cs;
};

template<typename POOLTYPE,typename LOCKTYPE>
class CMTMemoryPool
{
    public:
        void* Alloc(unsigned int size)
        {
            void* p =NULL;
           m_lock.Lock();
            p =m_pool.Alloc(size);
           m_lock.Unlock();

           return p;
        }

       void Free(void* p)
        {
           m_lock.Lock();
           m_pool.Free(p);
           m_lock.Unlock();   
        }

    private:
        POOLTYPE m_pool;
        LOCKTYPE m_lock;
};

//Test code
#include <iostream>
#include <windows.h>

using namespace std;

#include"MemoryPool.h"
#include "MTMemoryPool.h"

class CTest
{
public:
    int m_n;
    int m_n1;

    void*operator new(size_t size)
    {
        void* p = s_pool->Alloc(size);
        return p;
    }

    voidoperator delete(void* p, size_t size)
    {
        s_pool->Free(p);
    }

    staticvoid NewPool()
    {
        //s_pool = newCMemoryPool<CTest>;
        s_pool = newCMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>;
    }

    staticvoid DeletePool()
    {
        delete s_pool;
        s_pool = NULL;
    }
   
    //static CMemoryPool<CTest>* s_pool;
    static CMTMemoryPool<CMemoryPool<CTest>,CCriticalSection>* s_pool;
};

//CMemoryPool<CTest>*CTest::s_pool = NULL;
CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>* CTest::s_pool= NULL;

void testFun()
{
    int i;
    const int nLoop = 10;
    const int nCount = 10000;
   
    for(int j = 0; j<nLoop; ++j)
    {
        typedef CTest* LPTest;
        LPTest arData[nCount];
        for(i=0;i <nCount; ++i)
        {
            arData[i] =new CTest;
        }

       for(i=0;i <nCount; ++i)
        {
            deletearData[i];
        }
    }
}

int main(int argc, char*argv[])
{
    {
        unsigned int dwStartTickCount =GetTickCount();

       CTest::NewPool();

       testFun();
       
        CTest::DeletePool();
       
        cout << "total cost"<< GetTickCount() - dwStartTickCount << endl;
    }


    system("pause");

    return 0;
}

 

你可能感兴趣的:(C++,线程池)