分享一个对象池,资源管理代码片段


#1
template < typename T >
struct object_pool_traits_t;

template < typename T, typename AllocatorT >
struct object_pool_traits_t<std::list<std::shared_ptr<T>, AllocatorT>>
{
	typedef std::shared_ptr<T> value_t;

	static value_t pop(std::list<value_t, AllocatorT> &l)
	{
		if( l.empty() )
		{
			value_t val = std::make_shared<T>();
			return val;
		}
		else
		{
			value_t val = l.front();
			l.pop_front();
			return val;
		}
	}

	static void push(std::list<value_t, AllocatorT> &l, value_t && val)
	{
		l.push_back(std::move(val));
	}
};


template < 
	typename T,
	typename C = std::list<std::shared_ptr<T>>
> 
struct object_pool_t
{
	typedef std::shared_ptr<T> value_t;
	typedef C queue_t;
	typedef std::shared_ptr<queue_t> pool_t;
	
	static_assert(std::is_same<value_t, typename queue_t::value_type>::value, "container value_type must be std::shared_ptr<T> type");

	pool_t pool_;

	object_pool_t()
		: pool_(std::make_shared<queue_t>())
	{}

	template < typename AllocatorT = std::allocator<char> >
	value_t get(const AllocatorT &allocator = AllocatorT())
	{
		value_t obj = object_pool_traits_t<queue_t>::pop(*pool_);

		return std::shared_ptr<T>(obj.get(), 
								  [=](T *) mutable 
		{ 
			object_pool_traits_t<queue_t>::push(*pool_, std::move(obj));
		}, allocator);
	}
	
};

这是利用C++11新特性做的,对pool的容器做了正交分解


#2

这拿来做啥的?

不明觉厉.


#3

就一个对象池,只是想表达一下,C++在资源管理上确实下足了功夫,所以代码很简单


#4

支持!代码还没细看,貌似没有看到使用说明啊


#5

template <class Allocator = HeapAllocator>
class PeakObjectPool  {
private:
    union __Block{
        __Block* next;
        byte*    data;
    };

public:
    explicit PeakObjectPool(uint32 objSize, uint32 objCount = 32)
        : _pool(NULL)
        , _freeBlock(NULL)
        , _objSize(0)
        , _objCount(objCount)
        , _allocCount(0) {
        _objSize = objSize < 4 ? ALIGN_PTR(objSize, 4) : ALIGN_PTR(objSize, 2);
        createNew();
    }

    ~PeakObjectPool() {
        while (_pool) {
            __Block* ptr = _pool;
            _pool = _pool->next;
            _allocator.dealloc(ptr);
        }
    }

    inline void* alloc() {
        if (_freeBlock) {
            __Block* ptr = _freeBlock;
            _freeBlock = _freeBlock->next;
            assert(ptr != NULL);
            return ptr;
        }

        if (_allocCount == _objCount) {
            if (_objCount < 4096)
                _objCount += _objCount;
            if (!createNew())
                return NULL;
        }

        assert(_pool);
        byte* ptr = (byte*)_pool + 4 + _allocCount * _objSize;
        ++_allocCount;
        assert(ptr != NULL);
        return ptr;
    }

    inline void dealloc(void* ptr) {
        __Block* block = (__Block*)ptr;
        block->next = _freeBlock;
        _freeBlock = block;
    }

private:
    inline bool createNew() {
        byte* data = (byte*)_allocator.alloc(_objSize * _objCount + 4);
        assert(data);
        if (!data) {
            return false;
        }

        __Block* block = (__Block*)data;
        _allocCount = 0;
        if (_pool) {
            block->next = _pool;
            _pool = block;
        }
        else {
            _pool = block;
            _pool->next = NULL;
        }
        return true;
    }

private:
    Allocator _allocator;
    __Block* _pool = NULL;
    __Block* _freeBlock = NULL;
    uint32    _objSize = 0;
    uint32    _objCount = 0;
    uint32    _allocCount = 0;
};

#6

obj 的类型居然不是模板参数 这样不好不好 丢失了类型了

你这对象池会调用构造函数么? 会调用析构函数么?

如果不会调用对象的构造析构函数, 如何支持 RAII ? 如何进行资源管理?


#7

template<class T, class Allocator = HeapAllocator, class Pool = PeakObjectPool<Allocator>>
class ObjectPool
{
public:
    ObjectPool()
        : _pool(sizeof(T)) {
    }

    template<typename... Args>
    T* alloc(Args&& ... args) {
        T* ptr = reinterpret_cast<T*>(_pool.alloc());
        new (ptr)T(args...);
        return ptr;
    }

    void dealloc(T* ptr) {
        ptr->~T();
        _pool.dealloc(ptr);
    }
protected:
    Pool _pool;
};


#8

POD 类型无需调用构造函数和析构函数

这个优化你没有.


#9

对象没有使用到怎么销毁,多久清理一次内存?