zoukankan      html  css  js  c++  java
  • 【C++服务端技术】对象池

    代码没贴全,就少一个锁头文件,可以做设计参考

    设计思想就是维护一个空闲链表,没有用的就重新申请,有的话就拿链表的头,使用完又还给空闲链表。

    /*
    一个分配固定大小内存的内存池,使用链表维护
    
    */
    #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;
    }
    
  • 相关阅读:
    结对编程
    个人项目(JUnit单元测试)
    我的第一个GitHub仓库
    Visual Studio 创建C++或C#Windows程序
    字符串操作
    练习数值计算
    Hello World
    ceph部署出现错误及解决
    asp.net mvc 用Redis实现分布式集群共享Session。
    Unable to load DLL 'rasapi32.dll': 动态链接库(DLL)初始化例程失败。
  • 原文地址:https://www.cnblogs.com/byfei/p/14104066.html
Copyright © 2011-2022 走看看