线程安全内存池

#ifndef _INCLUDE_THREADSAFEMEM_H_
#define _INCLUDE_THREADSAFEMEM_H_
#include "MemPoolTemplate.h"
#include "FixLenMemPoolLock.h"

#define MAXWORKTHREADNUM 7//最多7个工作线程

namespace XUANXUAN
{
class CThreadSafeMemQueue;
class CThreadSafeMemFactory;
//////////////////////////////////////////////////////////////////////////
//线程安全缓存 CThreadSafeMem
//1.数据线程建立数据项目,设置绑定用户数目分发到各IO线程,并投递到循环回收线程
//2.IO线程对相关用户处理完一次解绑定 AddBindCount
//3.回收线程轮询调用 CanFreeSafeMem  返回true就可以释放内存
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMem
{
public:
    friend class CThreadSafeMemFactory;
    friend class CThreadSafeMemQueue;
public:
    //设置内存相关处理数据的线程数目   
    static void SetReactorNum(unsigned short nIONum);
    //检测所有相关处理线程是否已经处理完毕
    bool CanFreeSafeMem() const;
    //设置最大相关用户数目
    void MaxBindCount(unsigned short nRefCount) const;
    //相关处理线程每处理完数据就调用一次
    void AddBindCount(unsigned short nHIndex) const;
    //获得缓存头指针
    const char* GetMemHead() const;
    //获得缓存长度
    unsigned int GetMemLen() const;
private:
    CThreadSafeMem(const char* pOrgMem,unsigned int nOrgLen);
    ~CThreadSafeMem();
private:
    static unsigned short s_nReactorNum;                    //IO线程数目
    mutable const CThreadSafeMem* m_pNextSafeMem;           //下一个消息缓存
    mutable unsigned short m_wBindCount[MAXWORKTHREADNUM+1];//各线程操作句柄
    const unsigned int m_nSize;
    char m_pMemData[1];
};

class IThreadSafeMemQueueDelegate
{
public:
     virtual void freeThreadSafeMemProxy(const CThreadSafeMem* &pSafeMem) = 0;
};
//////////////////////////////////////////////////////////////////////////
//线程安全缓存队列 CThreadSafeMemQueue
//链接等待回收的线程安全缓存
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMemQueue
{
public:
    CThreadSafeMemQueue(IThreadSafeMemQueueDelegate* pDelegate);
    ~CThreadSafeMemQueue();
public:
    //增加数据项
    void pushback(list<const CThreadSafeMem*>& listSafeMem);
    //释放可回收的数据
    bool CanFreeSafeMem();
private:
    void pushback(const CThreadSafeMem*& pSafeMem);
private:
    IThreadSafeMemQueueDelegate* const m_pSafeMemDelegate;
    const CThreadSafeMem* m_pHead;
    const CThreadSafeMem* m_pTail;
};

//////////////////////////////////////////////////////////////////////////
//线程安全缓存内存池CThreadSafeMemFactory
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMemFactory:public IThreadSafeMemQueueDelegate
{
public:
    CThreadSafeMemFactory();
    const CThreadSafeMem* NewSafeMem(const char* pOrgMem,unsigned int nOrgLen);
    void GetMemInfo(string& strMemInfo);
protected:
    virtual void freeThreadSafeMemProxy(const CThreadSafeMem* &pSafeMem);
private:
    CMemPoolTemplate<CFixLenMemPoolLock> m_memPool;
};
}
#endif


#include "ThreadSafeMem.h"
#include <assert.h>
#include <string.h>
namespace XUANXUAN
{
unsigned short CThreadSafeMem::s_nReactorNum = MAXWORKTHREADNUM;

CThreadSafeMem::CThreadSafeMem(const char* pOrgMem,unsigned int nOrgLen)
    :m_pNextSafeMem(NULL)
    ,m_nSize(nOrgLen)
{
    memset(m_wBindCount,0,sizeof(m_wBindCount));
    memcpy(m_pMemData,pOrgMem,m_nSize);
}

CThreadSafeMem::~CThreadSafeMem()
{

}

unsigned int CThreadSafeMem::GetMemLen() const
{
    return m_nSize;
}

const char* CThreadSafeMem::GetMemHead() const
{
    return m_pMemData;
}

void CThreadSafeMem::SetReactorNum( unsigned short nIONum )
{
    s_nReactorNum = nIONum;
}

bool CThreadSafeMem::CanFreeSafeMem() const
{
    unsigned short localUnRefCount=0;
    for (unsigned short i=0;i<s_nReactorNum;++i)
    {
        localUnRefCount += m_wBindCount[i];
    }
    return m_wBindCount[MAXWORKTHREADNUM] == localUnRefCount;
}

void CThreadSafeMem::AddBindCount(unsigned short nHIndex) const
{
    assert(nHIndex<MAXWORKTHREADNUM);
    m_wBindCount[nHIndex]++;
}

void CThreadSafeMem::MaxBindCount(unsigned short nRefCount) const
{
    m_wBindCount[MAXWORKTHREADNUM] = nRefCount;
}

CThreadSafeMemQueue::CThreadSafeMemQueue( IThreadSafeMemQueueDelegate* pDelegate )
    :m_pSafeMemDelegate(pDelegate)
    ,m_pHead(NULL)
    ,m_pTail(NULL)
    {

    }

CThreadSafeMemQueue::~CThreadSafeMemQueue()
    {
    while(CanFreeSafeMem());
    }

void CThreadSafeMemQueue::pushback( list<const CThreadSafeMem*>& listSafeMem )
    {
    while(listSafeMem.empty()==false)
        {
        pushback(listSafeMem.front());
        listSafeMem.pop_front();
        }
    }

void CThreadSafeMemQueue::pushback( const CThreadSafeMem*& pSafeMem )
    {
    if (pSafeMem)
        {
        pSafeMem->m_pNextSafeMem = NULL;
        if (m_pTail)
            {
            m_pTail->m_pNextSafeMem = pSafeMem;
            m_pTail = pSafeMem;
            }
        else
            {
            m_pHead = m_pTail = pSafeMem;
            }
        pSafeMem = NULL;
        }
    }
bool CThreadSafeMemQueue::CanFreeSafeMem()
{
    bool bRet = false;
    while(m_pHead && m_pHead->CanFreeSafeMem())
    {
        bRet = true;
        const CThreadSafeMem* pTemp = m_pHead;
        m_pHead = pTemp->m_pNextSafeMem;
        m_pSafeMemDelegate->freeThreadSafeMemProxy(pTemp);
    }
    if (m_pHead==NULL)
    {
        m_pTail = NULL;
    }
    return bRet;
}

CThreadSafeMemFactory::CThreadSafeMemFactory()
{
    m_memPool.SetPoolName("CSafeMemFactory");
}

const CThreadSafeMem* CThreadSafeMemFactory::NewSafeMem( const char* pOrgMem,unsigned int nOrgLen )
{
    CThreadSafeMem* pSafeMem = new (m_memPool.GetMemByLen(sizeof(CThreadSafeMem)+nOrgLen))CThreadSafeMem(pOrgMem,nOrgLen);
    return pSafeMem;
}

void CThreadSafeMemFactory::GetMemInfo( string& strMemInfo )
{
    m_memPool.GetMemInfo(strMemInfo);
}

void CThreadSafeMemFactory::freeThreadSafeMemProxy( const CThreadSafeMem* &pSafeMem )
{
    if (pSafeMem)
    {
        char* pCircleMem = (char*)pSafeMem;
        m_memPool.PutMemByLen(pCircleMem,sizeof(CThreadSafeMem)+pSafeMem->GetMemLen());
        pSafeMem = NULL;
    }
}
}

猜你喜欢

转载自blog.csdn.net/XiaoWhy/article/details/77524190
今日推荐