c++实现,对象池 object_pool
生活随笔
收集整理的這篇文章主要介紹了
c++实现,对象池 object_pool
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
簡言
1. boost的對象池object_pool在釋放時采用的遍歷,有性能問題
2. 也不是什么大問題,優(yōu)化后可用。但是僅僅為了一個對象池,引入boost,沒必要
3. 筆者這里一份簡單實現(xiàn)的對象池,windows和linux下通用
4. 代碼量很小,僅僅兩百行,支持對象池高峰過后,逐步回收
?
接口介紹
1.?// 初始化(初始數(shù)量,一次增長的數(shù)量, 單次收縮的數(shù)量)
bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50);
2. // 分配一個新對象
?? ?T* alloc();
3.?// 回收一個對象
?? ?void dealloc(T* pObj);
4.?// 執(zhí)行一次回收,用來使用高峰過后的縮減
?? ?void dorecycle();
?
代碼下載地址
windows版:https://download.csdn.net/download/yzf279533105/11989303
實驗如下圖(特意標記出來兩次回收之后的,每次回收50個,空閑列表free_list的數(shù)量)
完整代碼
#pragma once#include <unordered_set> #include <string.h>//對象池模板類 template<class T> class class_obj_pool { public:enum{MAX_INIT_NUM = 100000, // 初始化最大數(shù)量,暫定10萬};class_obj_pool(){clear();}~class_obj_pool(){clear();} public:// 初始化(初始數(shù)量,一次增長的數(shù)量, 單次收縮的數(shù)量)bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50){// 參數(shù)檢測if (initNum <= 0 || increaseNum <= 0 || reduceNum <= 0){printf("init(), param error, initNum=%d, nIncreaseNum=%d, reduceNum=%d\n", initNum, increaseNum, reduceNum);return false;}nInitNum = initNum;nIncreaseNum = increaseNum;nShrinkNum = reduceNum;// 參數(shù)修正nInitNum = nInitNum>MAX_INIT_NUM ? MAX_INIT_NUM : nInitNum; // 初始個數(shù)nIncreaseNum = nIncreaseNum>MAX_INIT_NUM ? MAX_INIT_NUM : nIncreaseNum; // 一次增長的數(shù)量// 初始化對象for (int i = 0; i<nInitNum; ++i){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("new obj failed \n");continue;}// T對象需提供init函數(shù)進行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}free_list.insert(pObj);}return true;}// 分配一個新對象T* alloc(){T* pRet = NULL;// 空閑列表中有,則取一個if (free_list.size() > 0){unordered_set<T*>::iterator iter = free_list.begin();pRet = *iter;free_list.erase(iter);used_list.insert(pRet);// 超過最大使用記錄量,則更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 空閑列表中沒有時,則新建一批for (int i = 0; i<nIncreaseNum; i++){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("alloc(), new obj failed \n");continue;}// T對象需提供init函數(shù)進行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}// 沒賦值的先賦值;已賦值的壓入空閑列表if (pRet == NULL){pRet = pObj;used_list.insert(pObj);}else{free_list.insert(pObj);}}// 超過最大使用記錄量,則更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 回收一個對象void dealloc(T* pObj){if (pObj == NULL){printf("dealloc(), pObj == NULL");return;}// 不存在unordered_set<T*>::iterator it = used_list.find(pObj);if (it == used_list.end()){printf("dealloc(), find pObj failed \n");return;}// T對象需提供reset()函數(shù)進行重置pObj->reset();free_list.insert(pObj);used_list.erase(pObj);}// 執(zhí)行一次回收,用來使用高峰過后的縮減void dorecycle(){// 空閑列表中有對象,且超過一次增量時,才進行回收int nfree = free_list.size();if (nfree <= nIncreaseNum){return;}// 要回收的數(shù)量nfree = (nfree - nIncreaseNum);int i = 0;for (unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end();){T* pObj = *iter;if (pObj != NULL){delete pObj;}free_list.erase(iter++);// 超過一次回收的最大量,就跳出i++;if (i>=nShrinkNum){break;}}}// 打印出各個變量void showinfo(){printf("free_list.size=%d, used_list.size=%d, nUsedMax=%d \n", free_list.size(), used_list.size(), nUsedMax);}// 回收void clear(){for (std::unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}free_list.clear();for (std::unordered_set<T*>::iterator iter = used_list.begin(); iter != used_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}used_list.clear();nInitNum = 0; // 初始個數(shù)nUsedMax = 0; // 曾經(jīng)使用的最大個數(shù)nIncreaseNum = 0; // 一次增長的數(shù)量nShrinkNum = 0; // 單次回收的最大數(shù)量} private:std::unordered_set<T*> free_list; // 空閑列表std::unordered_set<T*> used_list; // 使用中的列表int nInitNum; // 初始個數(shù)int nUsedMax; // 曾經(jīng)使用的最大個數(shù)int nIncreaseNum; // 一次增長的數(shù)量int nShrinkNum; // 單次回收的最大數(shù)量 };?
總結
以上是生活随笔為你收集整理的c++实现,对象池 object_pool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏服务器正式发布时动态库处理的两种策略
- 下一篇: redis实现简单限流