c++简单对象池(或连接池)的实现

在服务器的开发中,对象池或者连接池的使用有两种特别的使用场景:一是对象的产生和销毁会消耗很大,二是对象的数量受到限制,比如mysql的连接对象。这个时候就可以采用池化的技术来解决该问题。池化的意思就是将对象一开始创建好放进池中,当需要时,从里面去,不需要时,在放回池中。

#ifndef __OBJECT_POOL_H__
#define __OBJECT_POOL_H__
#include <queue>
#include <mutex>
#include <memory>

#include "nocopyable.h"

//传入的T是一个裸指针
template <typename T>
class ObjectPool
	:public nocopyable
{
public:
	ObjectPool(size_t chunk_size = pool_size);
	virtual ~ObjectPool();

	//从对象池中去除一个对象
	std::shared_ptr<T> Take_out_object();
	//将使用的对象放回到对象池中
	void Put_back_object(std::shared_ptr<T> obj);

protected:
	//分配对象池
	void allocate_chunk();
	//构造一个对象
	inline static std::shared_ptr<T> construct();

private:
	std::queue<std::shared_ptr<T>> m_free_list;
	size_t m_chunk_size;             //对象池中预分配对象个数
	std::mutex     m_mutex;			//锁空闲对象队列的
	static const int pool_size = 50; //默认给定的对象池中的大小
};

template <typename T>
std::shared_ptr<T> ObjectPool<T>::construct()
{
	return std::shared_ptr<T>(new T);
}

template <typename T>
ObjectPool<T>::ObjectPool(size_t chunk_size) : m_chunk_size(chunk_size)
{
	if (m_chunk_size <= 0)
	{
		std::cout << "Object size invalid" << std::endl;
	}
	else
	{
		for (size_t i = 0; i != m_chunk_size; ++i)
		{
			allocate_chunk();
		}
	}
}

template <typename T>
ObjectPool<T>::~ObjectPool()
{
}

template <typename T>
void ObjectPool<T>::allocate_chunk()
{
	std::unique_lock<std::mutex> _(m_mutex);
	m_free_list.push(construct());
}

//注意:该内存池采用的是动态增长,即对象不够时,会重新创建对象,但是不会释放对象。所以解决
//了对象数量不容易设置合理的问题,但是却存在对象没有缩减的现象
template <typename T>
std::shared_ptr<T> ObjectPool<T>::Take_out_object()
{
	std::unique_lock<std::mutex> _(m_mutex);
	if (m_free_list.empty())
	{
		allocate_chunk();
	}
	std::shared_ptr<T> obj = m_free_list.front();
	m_free_list.pop();
	return obj;
}

template <typename T>
void ObjectPool<T>::Put_back_object(std::shared_ptr<T> obj)
{
	std::unique_lock<std::mutex> _(m_mutex);
	m_free_list.push(obj);
}

#endif //!__OBJECT_POOL_H__

测试:

#include <iostream>
#include "ObjectPool.hpp"
using namespace std;
class A
{
public:
	A() { std::cout << "A 的构造" << std::endl; }
	~A() { std::cout << "A的析构" << std::endl; }
	void sss(){ std::cout << "hello 对象池" << std::endl; }
};
int main()
{
	{
		ObjectPool<A>     opool(2);
		auto item = opool.Take_out_object();
		item->sss();
		opool.Put_back_object(item);
		
		auto item2 = opool.Take_out_object();
		item2->sss();

		item = opool.Take_out_object();
		item->sss();
		opool.Put_back_object(item);

		opool.Put_back_object(item2);
	}
	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值