对象池 定长内存池

~对象池

#ifndef __object_pool__ 
#define __object_pool__

#pragma once 
#include "mutex_lock.h"


#define STRUCT_FIELD(address, type, field) ((type *)((char*)(address) - (size_t)(&((type *)0)->field)))
#define FIELD_STRUCT(address, type, field) ((type *)((char*)(address) + (size_t)(&((type *)0)->field)))
/*
   对象池设计原理 
   list--------|tag|tag|tag|tag|tag-----100个|  
   list.next--------下一个list 
    
   tag---------tag---------tag--------下一个tag(这些tag都在list中)
   tag.obj----------真正的obj对象
*/

template<typename OBJTYPE>
class object_pool
{
#define _OBJ_STEP 100	
public:
	object_pool() {__init();}
	~object_pool() {__uninit();}
	
	OBJTYPE* pop(){return __pop();}
	bool push(OBJTYPE*& pobj) {return __push(pobj);}
	
private:
	void __init()
	{
		m_phead = 0;
		m_plist = 0;
		m_cur_count = 0;
		m_free_count = 0;
	}
	
	void __uninit()
	{
		c_mutex mutex(&m_lock);
		
		tag_obj_list* plist = m_plist, *qlist = 0 ;//删除list
		while(plist)
		{
			qlist = plist->next;
			delete plist;
			plist = qlist;		
		}
		
		m_phead = 0;
		m_plist = 0;
		m_cur_count = 0;
		m_free_count = 0;
	}
	 
	bool __push(OBJTYPE*& pobj)
	{
		if(!pobj) return false;
		tag_obj* ptag = FIELD_STRUCT(pobj,tag_obj,obj);
		
		c_mutex mutex(&m_lock); 
		if(!ptag || ptag->b_in_pool) return false;
		
		//头插法
		if(m_phead)
		{
			ptag->next = m_phead;
			m_phead = ptag;
		}
		else
		{
			m_phead = ptag;
			ptag->next = 0;
		}
		
		pobj = 0;
		ptag->b_in_pool = true;
		m_free_count++;
		printf("obj_pool push free_count=%d  cur_count=%d\n",m_free_count,m_cur_count);
		
		return false;
	}
	
	OBJTYPE* __pop()
	{
		c_mutex mutex(&m_lock); 

		if(!m_phead && !__create_block()) return 0;
		
		//头取法
		tag_obj* ptag = m_phead;
		m_phead = m_phead->next;
		
		ptag->b_in_pool = false;
		m_free_count--;
		
		printf("obj_pool pop free_count=%d  cur_count=%d\n",m_free_count,m_cur_count);
		
		return (OBJTYPE*)STRUCT_FIELD(ptag,tag_obj,obj);
	}
	
	bool __create_block()
	{
		tag_obj_list* plist = new tag_obj_list;
		if(!plist) return false;
		
		if(m_plist)
		{
			plist->next = m_plist;
			m_plist = plist;
		}
		else 
		{
			m_plist = plist;
			m_plist->next = 0;
		}
		
		for(int i = 0; i< _OBJ_STEP;i++)  //创建100个obj
		{
			plist->list[i].b_in_pool = false;
			plist->list[i].next = 0;
			
			OBJTYPE* q = &(plist->list[i].obj);
			
			if(__push(q)) return false;
			m_cur_count++; //放入成功 cur_count+1
		}
		return true;
	}

private:
#pragma pack(push,1)
	struct tag_obj
	{
		OBJTYPE 				obj;
		bool 					b_in_pool;
		tag_obj* 				next;
	};
    struct tag_obj_list{
        tag_obj_list* 			next;
        tag_obj  				list[_OBJ_STEP];
    };		
#pragma pack(pop)

	mutex_lock	    m_lock;
	tag_obj*		m_phead;
	tag_obj_list*	m_plist;
	int				m_cur_count;
	int				m_free_count;
};

#endif 

 

~内存池

#ifndef __mem_pool__
#define __mem_pool__

#pragma once 

#include "mutex_lock.h"
#include "comm.h"


#define  SHRINK_SPACE  1000*5       //内存池缩减时间间隔
#define  SHRINK_COUNT  10           //每次缩减个数
#define  SHRINK_TIME   1000         //内存空闲多长时间可释放

//c++中new开辟内存时会额外开辟数据头记录相关信息,以便在删除内存时知道需要删除多少  /tag/mem/tag/mem
typedef void TBLOCK;

#pragma pack(push,1)
struct tagblock
{
	int 	 size:31; 	  //开辟内存大小
	int	 	 status:1;    //是否在池中
	_uint32	 code;        //校验码
	_uint32	 utime; 	  //buff创建时间
	TBLOCK*	 next;		  //下一个buff
	
	tagblock()
	{
		size = 0;
	    status = 0;
	    code = 0;
		utime = 0;
		next = 0;
	}
};
#pragma pack(pop)

namespace comm_tblock
{	
	static _uint32 _code(tagblock* ptag) 
	{
		return size_t(&ptag->code);
    }

    static tagblock* _head_tblock(TBLOCK* p)
	{
		return (p ? (tagblock*)((char*)p - sizeof(tagblock)): NULL);
	}
	
	static int _tblock_size(TBLOCK* p)
	{
		tagblock* ptag = _head_tblock(p); 
		return ptag ? ptag->size : 0;
	}
	
	static void _free_tblock(TBLOCK* p) 
	{
		delete ((char*)p - sizeof(tagblock));
	}
	
	static TBLOCK* _create_tblock(int size)
	{
		if(size <= 0) return 0;
	
		char* pbf = new char[sizeof(tagblock) + size];
		if(!pbf) return 0;
	
		tagblock* ptag = (tagblock*)pbf;
		memset(ptag, 0, sizeof(tagblock));
		ptag->size = size;
		ptag->code = _code(ptag);
	
		return (TBLOCK*)((char*)ptag + sizeof(tagblock));
	}
	
	static tagblock* _check_tblock(TBLOCK* p) 
	{
		tagblock* ptag = _head_tblock(p); 
		return (!ptag || (ptag->code != _code(ptag))) ? 0 : ptag;
	}
	
	static TBLOCK*	_bf_get_next(TBLOCK* p)
	{
		tagblock* ptag = _head_tblock(p);
		return (ptag ? ptag->next : 0);
	}
	
	static bool _bf_set_next(TBLOCK* p,TBLOCK* q)
	{
		tagblock* ptag = _head_tblock(p);
		if(!ptag) return false;
		
		ptag->next = q;
		
		return true;
	}

};


//根据TBLOCK指针找到tagblock
#define _HEAD_TBLOCK(p) comm_tblock::_head_tblock(p)
//计算tagblock.code
#define _CODE(p)  comm_tblock::_code(p)
//释放TBLOCK
#define _FREE_TBLOCK(p) comm_tblock::_free_tblock(p)
//创建TBLOCK
#define _CREATE_TBLOCK(size) comm_tblock::_create_tblock(size)
//设置后一个TBLCOK
#define _TBLOCK_GET_NEXT(p) comm_tblock::_bf_get_next(p)
//设置后一个TBLCOK
#define _TBLOCK_SET_NEXT(p,q) comm_tblock::_bf_set_next(p,q)
//检测tagblock.code
#define _CHECK_TBLOCK(p)  comm_tblock::_check_tblock(p)
//block大小
#define _TBLOCK_SIZE(p)  comm_tblock::_tblock_size(p)



class block_pool
{
public:
	block_pool();
	~block_pool();
	
	bool    init(int block_size,int init_count);
	void    uninit();
	
	TBLOCK* pop();	//取出一个TBLOCK
	bool    push(TBLOCK*& p); //放入一个TBLOCK
	void    shrink(_uint32 * now_msec = 0); //定时释放空闲内存块
  
	int	    block_size() {c_mutex mutex(&m_lock); return m_block_size;}
	int     cur_count() {c_mutex mutex(&m_lock); return m_cur_count;}
	int	    free_count() {c_mutex mutex(&m_lock); return m_free_count;}

private:
	bool    new_block();
	
private:
	mutex_lock	    m_lock;
	TBLOCK*			m_p_list_head;		 //指向内存链表第一个TBLOCK
	TBLOCK*			m_p_list_tail;		 //指向内存链表最后TBLOCK
	
	int				m_block_size;  		 // TBLOCK大小		
	int				m_cur_count;    	 //当前TBLOCK数量
	int				m_free_count;   	 //空闲TBLOCK数量	
	_uint32			m_last_shrink_time;	 //上次释放空闲内存时间
};

#define BFTYPE_COUNT 20         //类型个数
#define BFTYPE_64B   64         // 0
#define BFTYPE_128B  128        // 1
#define BFTYPE_256B  256        // 2
#define BFTYPE_512B  512        // 3
#define BFTYPE_1K    1024       // 4
#define BFTYPE_2K    2048       // 5
#define BFTYPE_4K    4096       // 6
#define BFTYPE_8K    8192       // 7
#define BFTYPE_16K   16384      // 8
#define BFTYPE_32K   32768      // 9
#define BFTYPE_64K   65536      // 10
#define BFTYPE_128K  131072     // 11
#define BFTYPE_256K  262144     // 12
#define BFTYPE_512K  524288     // 13
#define BFTYPE_1M    1048576    // 14
#define BFTYPE_2M    2097152    // 15
#define BFTYPE_4M    4194304    // 16
#define BFTYPE_8M    8388608    // 17
#define BFTYPE_16M   16777216   // 18
#define BFTYPE_32M   33554432   // 19

//内存池原理 预开辟多个内存块链表 开放接口取出放回指定长内存块 
class block_pool_ex
{
public:
	block_pool_ex();
	~block_pool_ex();
	
	TBLOCK* pop(_uint32 size);
	bool 	push(TBLOCK* p);
	void 	shrink(_uint32* now_msec = 0);
	
private:
    inline int _index(_uint32 size);
    block_pool  m_pool_list[BFTYPE_COUNT];	
};

#endif

 

posted on 2015-03-25 00:26  kangbry  阅读(563)  评论(0编辑  收藏  举报

导航