对象池 定长内存池
~对象池
#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
本博客内容均来自网络,如有雷同,是我抄袭!