#ifndef OBJ_POOL_H
#define OBJ_POOL_H
#include <list>
#include <unordered_set>
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
template <typename T, typename ObjBuilder>
class ObjPool {
public:
ObjPool(int initSize, int maxSize) {
_initSize = initSize;
_maxSize = maxSize;
for (int i = 0; i < _initSize; ++i) {
T* t = build();
_objQueue.push_back(t);
}
}
~ObjPool() {
for (auto i : _objQueue) {
delete i;
}
_objQueue.clear();
for (auto i : _activeSet) {
delete (i);
}
_activeSet.clear();
}
T* get() {
bool objQueueIsEmpty = false;
{
std::lock_guard<std::mutex> lock_guard(_lock);
size_t objQueueIsEmpty = _objQueue.empty();
size_t activeSetSize = _activeSet.size();
if (objQueueIsEmpty && activeSetSize < _maxSize) {
T *t = build();
_activeSet.insert(t);
return t;
}
}
while (1) {
{
std::lock_guard<std::mutex> lock_guard(_lock);
objQueueIsEmpty = _objQueue.empty();
if (!objQueueIsEmpty) {
T* t = _objQueue.front();
_objQueue.pop_front();
_activeSet.insert(t);
return t;
}
}
//没获取到等待其他线程释放锁
std::unique_lock<std::mutex> lock(_waitMutex);
_waitConditionVariable.wait(lock);
}
assert(false);
}
void release(T* t) {
std::lock_guard<std::mutex> lock_guard(_lock);
if (_activeSet.find(t) != _activeSet.end()) {
_activeSet.erase(t);
}
_objQueue.push_back(t);
_waitConditionVariable.notify_one();
}
inline T* build() {
return ObjBuilder::build();
}
private:
std::list<T*> _objQueue;
std::unordered_set<T*> _activeSet;
int _initSize;
int _maxSize;
std::mutex _waitMutex;
std::condition_variable _waitConditionVariable;
std::mutex _lock;
};
//如果_instance 已经被销毁,这个怎么办
template <typename Pool, typename T>
class ObjPoolGuard {
public:
ObjPoolGuard(Pool* pool, T* t) {
_pool = pool;
_instance = t;
}
~ObjPoolGuard() {
if (_instance != nullptr) {
_pool->release(_instance);
}
}
private:
Pool* _pool;
T* _instance;
};
#ifdef TEST_OBJPOOL
class CTestObj{
public:
CTestObj(){
printf("new CTestObj \n");
}
void DoSomething(int i){
printf("new hahahahah \n");
}
};
class CTestBuild{
public:
static CTestObj* build(){
return new CTestObj();
}
};
typedef ObjPool<CTestObj,CTestBuild> TestPool;
void Process(void* v){
TestPool* pool = (TestPool*)v ;
CTestObj* obj = pool->get();
ObjPoolGuard<TestPool,CTestObj> aa(pool,obj);
obj->DoSomething(11);
sleep(1);
}
int main(int args ,char **argv){
TestPool* pool= new TestPool(2,5);
std::thread threads[10];
for (int i = 0; i < 10; ++i){
threads[i] = std::thread(Process, (void *)pool);
}
for (auto & th:threads)
th.join();
return 0;
};
#endif
#endif //OBJ_POOL_H
C++ 对象池模版
最新推荐文章于 2024-09-07 05:15:02 发布