为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

通用高效的c++内存池(特定类型)

2012-06-11 8页 doc 79KB 55阅读

用户头像

is_270459

暂无简介

举报
通用高效的c++内存池(特定类型)通用高效内存池的设计要点: 1)快速分配; 2)快速回收; 3)空间利用率高。 4)类型独立(最好)。 不打算对比各种内存分配器的优劣,主要是介绍一最近实现的特定类型的通用高效C++内存池。 特点: 1)基于共享内存; -- 不会因为进程挂掉而丢失数据。 2)快速分配; -- 在内存池接近满时,效率不高。 3)快速回收;-- 常数。 4)空间利用率高 -- 利用bit标识内存块使用与否 (《C++设计新思维》的小对象分配器不占用额外空间!!) 已知缺点: 1)在内存池接近满时,分配效率不高。 2)非类...
通用高效的c++内存池(特定类型)
通用高效内存池的要点: 1)快速分配; 2)快速回收; 3)空间利用率高。 4)类型独立(最好)。 不打算对比各种内存分配器的优劣,主要是介绍一最近实现的特定类型的通用高效C++内存池。 特点: 1)基于共享内存; -- 不会因为进程挂掉而丢失数据。 2)快速分配; -- 在内存池接近满时,效率不高。 3)快速回收;-- 常数。 4)空间利用率高 -- 利用bit标识内存块使用与否 (《C++设计新思维》的小对象分配器不占用额外空间!!) 已知缺点: 1)在内存池接近满时,分配效率不高。 2)非类型独立。每一种类型需要一特定内存池。 3)非线程安全,需要使用者自行保证。   1 #ifndef __Memory_POOL__H__ 2 #define __Memory_POOL__H__ 3 http://touxiang.qqq23.com 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 11 #include 12 #include "utilfunc.h" 13 14 15 template 16 struct MemPoolHead 17 { 18 size_t iTotalSize; // 19 size_t iCurSize; // 剩余空间数 20 size_t iNextPos; // 下一个可用位置,用于快速分配(循环分配) 21 size_t iRecordLen; 22 23 T arrDatas[0]; // 作为占位符,初始化后有效 24 25 MemPoolHead() 26 { 27 memset(this, 0, sizeof(MemPoolHead)); 28 } 29 }; 30 31 template 32 void PrintMemPoolHead(const MemPoolHead& stHead) 33 { 34 printf("iTotalSize=%zu, iCurSize=%zu, iNextPos=%zu, iRecordLen=%zu\n", 35 stHead.iTotalSize, stHead.iCurSize, stHead.iNextPos, stHead.iRecordLen); 36 } 37 http://name.ttplay8.cn 38 template 39 class MemoryPool 40 { 41 public: 42 MemoryPool(); 43 44 ~MemoryPool(); 45 46 int Init(int ishmKey); // for read exist data 47 48 int Init(int ishmKey, const MemPoolHead& stHeadInfo); // for creating 49 50 T* GetPos(); 51 52 void DelPos(T* pdata); 53 54 void PrintHead() const; 55 56 int DeleteShm(); 57 58 int Reset(); 59 60 T* NextElem(size_t* pIndex) const; 61 62 63 size_t Total() const; 64 65 size_t Size() const; 66 67 bool Empty() const; 68 69 bool IsFull() const; 70 71 private: 72 MemoryPool(const MemoryPool&); 73 MemoryPool& operator=(const MemoryPool&); 74 75 int m_ishmKey; 76 MemPoolHead* m_datas; 77 78 char* m_usedbits; // 标识特定内存块是否已使用 79 }; 80 81 82 template 83 MemoryPool::MemoryPool() 84 { 85 m_ishmKey = -1; 86 m_datas = NULL; 87 m_usedbits = NULL; 88 } 89 90 template 91 MemoryPool::~MemoryPool() 92 { 93 94 } 95 96 template 97 int MemoryPool::Init(int ishmKey, const MemPoolHead& stHeadInfo) 98 { 99 if( stHeadInfo.iCurSize > stHeadInfo.iTotalSize || stHeadInfo.iRecordLen != sizeof(T)){ 100 printf("Invalid parameters\n"); 101 return -1; 102 } 103 104 size_t size = sizeof(MemPoolHead) + (stHeadInfo.iTotalSize) * sizeof(T) + (stHeadInfo.iTotalSize / 8 + 1); 105 106 PrintMemPoolHead(stHeadInfo); 107 printf("Head len=%lu, Recode Len=%lu, shm Size=%lu\n", sizeof(MemPoolHead), sizeof(T), size); 108 109 int iCreate = false; 110 char* sShm = NULL; 111 if (!(sShm = UTIL::GetShm(ishmKey,size,0666&(~IPC_CREAT)))) 112 { 113 if (!(sShm = UTIL::GetShm(ishmKey,size,0666|IPC_CREAT))) 114 { 115 printf("get shm error!\n"); 116 return -2; 117 } 118 else 119 { 120 iCreate = true; 121 122 memset(sShm, 0, size); 123 } 124 } 125 126 m_datas = (MemPoolHead*)sShm; 127 m_ishmKey = ishmKey; 128 129 m_usedbits = sShm + sizeof(MemPoolHead) + (stHeadInfo.iTotalSize) * sizeof(T); 130 131 132 if( iCreate ){ 133 memcpy(m_datas, &stHeadInfo, sizeof(stHeadInfo)); 134 135 m_datas->iCurSize = 0; 136 m_datas->iNextPos = 0; 137 } 138 else { 139 if( stHeadInfo.iTotalSize != m_datas->iTotalSize || stHeadInfo.iRecordLen != m_datas->iRecordLen ) 140 { 141 printf("Memory head info is not matched!\n"); 142 PrintHead(); 143 144 m_datas = NULL; 145 m_ishmKey = -1; 146 return -1; 147 } 148 } 149 150 return 0; 151 } 152 153 template 154 int MemoryPool::Init(int ishmKey) 155 { 156 MemPoolHead stHead; 157 char* sShm = NULL; 158 if (!(sShm = UTIL::GetShm(ishmKey, sizeof(MemPoolHead), 0666&(~IPC_CREAT)))) { 159 return -1; 160 } 161 162 memcpy(&stHead, sShm, sizeof(MemPoolHead)); 163 164 return Init(ishmKey, stHead); 165 } 166 167 template 168 T* MemoryPool::GetPos() 169 { 170 if( NULL == m_datas || m_datas->iNextPos > m_datas->iTotalSize ){ 171 printf("Something wrong in memory pool!\n"); 172 return NULL; 173 } 174 175 if( m_datas->iCurSize >= m_datas->iTotalSize ){ 176 printf("Memory pool is full\n"); 177 return NULL; 178 } 179 180 T *pdata = NULL; 181 182 while(1){ 183 184 if( m_datas->iNextPos >= m_datas->iTotalSize ){ 185 m_datas->iNextPos = 0; 186 } 187 188 if( bit_test(m_usedbits, m_datas->iNextPos) ){ // pos is used 189 m_datas->iNextPos++; 190 continue; 191 } 192 else{ 193 bit_set(m_usedbits, m_datas->iNextPos); 194 195 pdata = &m_datas->arrDatas[m_datas->iNextPos++]; 196 m_datas->iCurSize ++; 197 break; 198 } 199 } 200 return pdata; 201 } 202 203 template 204 void MemoryPool::DelPos(T* pdata) 205 { 206 if( (char*)pdata >= (char*)m_datas + sizeof(MemPoolHead) && (char*)pdata < m_usedbits) 207 { 208 if( ((char*)pdata - ((char*)m_datas + sizeof(MemPoolHead))) % sizeof(T) == 0){ 209 size_t index = ((char*)pdata - ((char*)m_datas + sizeof(MemPoolHead))) / sizeof(T); 210 211 if( bit_test(m_usedbits, index) ){ 212 printf("delete pos: %p(%zu)\n", pdata, index); 213 214 memset(pdata, 0, sizeof(T)); 215 216 m_datas->iCurSize --; 217 218 bit_clear(m_usedbits, index); 219 } 220 } 221 } 222 } 223 224 template 225 void MemoryPool::PrintHead() const 226 { 227 if( NULL == m_datas ) return; 228 229 PrintMemPoolHead(*m_datas); 230 } 231 232 template 233 int MemoryPool::DeleteShm() 234 { 235 if( NULL == m_datas ) return 0; 236 237 shmdt(m_datas); 238 239 return UTIL::DeleteShm(m_ishmKey); 240 } 241 242 template 243 int MemoryPool::Reset() 244 { 245 if( NULL == m_datas ) return 0; 246 247 size_t size = (m_datas->iTotalSize) * sizeof(T) + (m_datas->iTotalSize / 8 + 1); 248 249 memset((char*)m_datas + sizeof(MemPoolHead), 0, size); 250 m_datas->iCurSize = 0; 251 m_datas->iNextPos = 0; 252 253 return 0; 254 } 255 256 template 257 T* MemoryPool::NextElem(size_t* pIndex) const 258 { 259 if( NULL == m_datas || NULL == pIndex ) return NULL; 260 261 while( *pIndex < m_datas->iTotalSize ) 262 { 263 size_t index = *pIndex; 264 if( bit_test(m_usedbits, index) ) 265 { 266 *pIndex = index + 1; 267 268 return &m_datas->arrDatas[index]; 269 } 270 *pIndex = index + 1; 271 } 272 273 return NULL; 274 } 275 276 template 277 size_t MemoryPool::Total() const 278 { 279 if( NULL == m_datas ) return 0; 280 281 return m_datas->iTotalSize; 282 } 283 284 template 285 size_t MemoryPool::Size() const 286 { 287 if( NULL == m_datas ) return 0; 288 289 return m_datas->iCurSize; 290 } 291 292 template 293 bool MemoryPool::Empty() const 294 { 295 if( NULL == m_datas ) return false; 296 297 return ( 0 == m_datas->iCurSize); 298 } 299 300 template 301 bool MemoryPool::IsFull() const 302 { 303 if( NULL == m_datas ) return true; 304 305 return (m_datas->iTotalSize == m_datas->iCurSize); 306 } 307 308 #endif
/
本文档为【通用高效的c++内存池(特定类型)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索