C++对象池以及shared_ptr的支持

对象池 和 支持对象池的shared_ptr

性能测试

数字的单位是微妙 分配5万个 1kb的object 

10 kb

100kb

500b

128b

因此 只考虑对象分配速度问题的话  大于 512的对象推荐使用pool版本

第一个是:自己实现的池容器  对象池

第二个是:make_shared   非对象池

第三个是:原始的new delete  非对象池

测试2:

和上上面的一样 只不过第一条数据是 std::queue 而非自己实现的容器

对于release 0x3优化 版本的测试 相差很大

 

32bytes

64bytes

128 bytes

512

10kb

因此综合来看 超过 32 字节的 都应该用pool来处理

Object.h

#pragma  once
/*
Email [email protected]

注意事项:
1.使用例子在cpp文件各种test函数里面
2.

class说明:
RawObject:
1.最原始的指针 只不过封装了一个release函数 用于delete this

RefObject:
1.简单的引用计数 需要手动去计数 Retain Release快速简单

RefObjectThreadSafe:
1.RefObject的线程安全版本 只保证计数安全

SharedObject:
1.std::enable_shared_from_this 封装 无需手动在继承 如果想用原始的std::shared_ptr可以继承方便使用

Recycleable:
1.对象池可回收对象 ctor和dtor需要重写 以供初始化内部数据

share_ptr:
1.ShareObjectPool 专有的指针类型 内部封装了std::shared_ptr,必需配合ShareObjectPool 使用


对象池:
ObjectPool :
1.64字节以上的class 都应该使用pool
2.对象池管理的对象必需是 RawObjectRecycleable OR RefObjectRecycleable OR Recycleable(需要手动调用ObjectPool::Release) 的子类
3.对于子类来说必需提供默认无参数构造函数public,对于构造方法请用其他方法(ctor or other member function)实现 而非依托于构造函数

ShareObjectPool:
1.64字节以上的class 都应该使用pool
2.该对象池相比ObjectPool 是share_ptr的专有对象池 利用share_ptr来管理对象的生命周期
3.管理的对象必需是 ShareObjectRecycleable 的子类
4.对于子类来说必需提供默认无参数构造函数public,对于构造方法请用其他方法(ctor or other member function)实现 而非依托于构造函数

TODO:
1.考虑是否不让new跑出异常而继续程序运行 new(std::nothrow)XX;
*/
#include <memory>
#include <atomic>
#include <mutex>

class Object
{
public:
};
//raw pointer object
class RawObject
{
public:
	/**
	* @brief  call this to delete object
	*/
	inline	virtual	 void Release()
	{
		delete this;
	}
	virtual	~RawObject()
	{

	}
};
//reference counter object
//this class is none-thread-safe, thread-safe replacer is (std::shared_ptr) or RefObjectThreadSafe
class RefObject
{
protected:
	int referenct_count = 1;
public:
	/**
	* @brief add reference count
	*/
	inline	void Retain()
	{
		++referenct_count;
	}
	/**
	* @brief  reduce reference count
	*/
	inline	virtual	void Release()
	{
		--referenct_count;
		if (referenct_count <= 0)
		{
			delete this;
		}
	}
	inline int GetReferenceCount()const
	{
		return referenct_count;
	}
	virtual	~RefObject()
	{

	}
	//TODO add this to auto release pool or add std::shared_ptr suport

};
//reference counter object
class RefObjectThreadSafe
{
protected:
	std::atomic<int> referenct_count = 1;
public:
	/**
	* @brief add reference count
	*/
	inline	void Retain()
	{
		++referenct_count;
	}
	/**
	* @brief  reduce reference count
	*/
	inline	virtual	void Release()
	{
		--referenct_count;
		if (referenct_count == 0)
		{
			delete this;
		}
	}
	inline int GetReferenceCount()const
	{
		return referenct_count;
	}
	virtual	~RefObjectThreadSafe()
	{

	}
	//TODO add this to auto release pool or add std::shared_ptr suport

};

//raw  share ptr wrapper class 
//create by std::make_shared ,pass object by share_from_this or std::shared_ptr's method
template<typename SubClassType>
class SharedObject :public std::enable_shared_from_this<SubClassType>
{
public:
	virtual ~SharedObject()
	{

	}
	//xxx->share_from_this();
};

//for object pool 
class Recycleable
{
public:
	/**
	* @brief when re-use this class this will be call
	*/
	virtual void ctor() = 0;
	/**
	* @brief when recycle by pool this will be call
	*/
	virtual void dtor() = 0;
	//tag for class  ObjectPool
	//泛型约束
	inline void ___type_sub_class_restrain__FOR_ObjectPool()
	{
	}
};

class NoneRecycleable
{
public:
	void ctor() = delete;
	void dtor() = delete;
};

template< class T, bool ThreadSafe>
class share_ptr;

//对象>=该大小时才会使用Pool 否则Pool会动态new 和delete
#define OBJECT_POOL_MIN_SIZEOF 32
//40KB 1w objects
#define OBJECT_POOL_MAX_SIZE 10240
//1Kb  为对象池 预分配的 队列空间 的个数大小
#define OBJECT_POOL_DEFAULT_ALLOC_SIZE 512
//对象池预分配对象大小 必需小于 OBJECT_POOL_DEFAULT_ALLOC_SIZE
#define OBJECT_POOL_DEFAULT_ALLOC_OBJECT_SIZE 256

template< typename ClassType, typename bool ThreadSafe = false>
class ObjectPool
{
	template< class ClassType, bool ThreadSafe = false>
	class Ctor
	{
	public:
		Ctor()
		{//ctor
			int capacity = ObjectPool<ClassType, ThreadSafe>::capacity;
			auto pool = ObjectPool<ClassType, ThreadSafe>::_pool;
			for (int i = 0; i < capacity; i++)
			{
				pool[i] = nullptr;
			}
		}
		~Ctor()
		{//dtor
			ObjectPool<ClassType, ThreadSafe>::Clear();
			//如果编译报错 那么证明不是约束下的 子类关系 请确认
			ClassType * s = nullptr;
			s->___type_sub_class_restrain__FOR_ObjectPool();
		}
	};
	ObjectPool();
	static int capacity;
	static ClassType** _pool;
	static int size;
	static std::mutex _mutex;
private:
	/**
	* @brief resize inner pool growing by twice
	* @warning this will copy old block and delete old
	*/
	static void ReSize()
	{
		auto pool = new ClassType*[capacity * 2];//
		memset(pool, 0, sizeof(ClassType*)* 2 * capacity);
		memcpy(pool, _pool, sizeof(ClassType*)* capacity);
		capacity *= 2;
		delete _pool;
		_pool = pool;
	}
	static void PreAlloc()
	{
		auto pool = _pool;
		for (int i = 0; i < OBJECT_POOL_DEFAULT_ALLOC_OBJECT_SIZE; i++)
		{
			pool[size] = new ClassType();
			++size;
		}
	}
public:
	/**
	* @brief  call this to new class who is the sub-class of Recycleable
	* @note if class size if smaller than OBJECT_POOL_MIN_SIZEOF will new otherwise will gen object from pool
	*/
	static ClassType* Create()
	{
		if (ThreadSafe)
		{
			ClassType * ret = nullptr;
			{
				std::lock_guard<std::mutex> locker(_mutex);
				static ObjectPool<ClassType, ThreadSafe>::Ctor<ClassType, ThreadSafe> ctor;//c11 compiler suport thread-safe
				if (size > 0 && sizeof(ClassType) >= OBJECT_POOL_MIN_SIZEOF)
				{
					--size;
					ret = (_pool[size]);
					_pool[size] = nullptr;
				}
			}
			if (!ret)
			{
				ret = new ClassType();
			}
			ret->ctor();
			return ret;
		}
		else
		{
			//ctor之所以弄为函数的static是因为全局的static析构并不完全和定义顺序一致 因为为了避免不同编译器下出错就放在这里了
			//局部的肯定比全局的先析构
			static ObjectPool<ClassType, ThreadSafe>::Ctor<ClassType, ThreadSafe> ctor;//c11 compiler suport thread-safe
			if (size > 0 && sizeof(ClassType) >= OBJECT_POOL_MIN_SIZEOF)
			{
				--size;
				ClassType* ret = (_pool[size]);
				_pool[size] = nullptr;
				ret->ctor();
				return ret;
			}
			auto ret = new ClassType();
			ret->ctor();
			return ret;
		}
	}
	/**
	* @brief release object to the pool
	* @note if sizeof class is smaller than OBJECT_POOL_MIN_SIZEOF will delete now otherwise will put into pool
	*/
	static void Release(ClassType* who)
	{
		if (!who)return;
		who->dtor();
		if (sizeof(ClassType) < OBJECT_POOL_MIN_SIZEOF)
		{
			delete who;
			return;
		}
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			if (size >= OBJECT_POOL_MAX_SIZE)
			{
				cout << capacity << " " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << " warnning Release out-of-size" << endl;
				delete who;
				return;
			}
			if (size >= capacity)
			{
				ReSize();
			}
			_pool[size] = who;
			++size;
		}
		else
		{
			if (size >= OBJECT_POOL_MAX_SIZE)
			{
				cout << capacity << " " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << " warnning Release out-of-size" << endl;
				delete who;
				return;
			}
			if (size >= capacity)
			{
				ReSize();
			}
			_pool[size] = who;
			++size;
		}
	}
	/**
	* @brief  delete all objects in this pool
	*/
	static void Clear()
	{
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			auto pool = _pool;
			auto _size = size;
			if (_size <= 0)return;
			for (int i = 0; i < _size; i++)
			{
				if (pool[i])
				{
					delete pool[i];
					pool[i] = nullptr;
				}
			}
			size = 0;
		}
		else
		{
			auto pool = _pool;
			auto _size = size;
			if (_size <= 0)return;
			for (int i = 0; i < _size; i++)
			{
				if (pool[i])
				{
					delete pool[i];
					pool[i] = nullptr;
				}
			}
			size = 0;
		}
	}
	inline static int Size()
	{
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			return  size
		}
		else
		{
			return  size;
		}
	}
	/**
	* @brief print current pool status for debug
	*/
	static	void PrintStatus()
	{
		int total = (sizeof(ClassType)* size);
		if (total < 1024)
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) << "B " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
		else if (total < 1024 * 1024)
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) / 1024.0 << "KB " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
		else
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) / 1024.0 / 1024.0 << "MB " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
	}
};
template<class ClassType, bool ThreadSafe>
ClassType**ObjectPool<ClassType, ThreadSafe>::_pool = new ClassType*[OBJECT_POOL_DEFAULT_ALLOC_SIZE];//
template<class ClassType, bool ThreadSafe>
int ObjectPool<ClassType, ThreadSafe>::size = 0;
template<class ClassType, bool ThreadSafe>
std::mutex ObjectPool<ClassType, ThreadSafe>::_mutex;
template<class ClassType, bool ThreadSafe>
int ObjectPool<ClassType, ThreadSafe>::capacity = OBJECT_POOL_DEFAULT_ALLOC_SIZE;




//自带share_ptr版本 无需手动调用 Object::Release
//适用于 SharedObjectRecycleable的子类的对象池
//因为模板的模板 特化 不好处理 因此干脆重新开个名字 ShareObjectPool
template< typename ClassType, typename bool ThreadSafe = false>
class ShareObjectPool
{
	/**
	* @brief inner ctor class for Pool
	*/
	template< class ClassType, bool ThreadSafe = false>
	class Ctor
	{
	public:
		Ctor()
		{//ctor
			int capacity = ShareObjectPool<ClassType, ThreadSafe>::capacity;
			auto pool = ShareObjectPool<ClassType, ThreadSafe>::_pool;
			for (int i = 0; i < capacity; i++)
			{
				pool[i] = nullptr;
			}
			ShareObjectPool<ClassType, ThreadSafe>::PreAlloc();
		}
		~Ctor()
		{//dtor
			ShareObjectPool<ClassType, ThreadSafe>::Clear();
			//如果编译报错 那么证明不是约束下的 子类关系 请确认
			ClassType * s = nullptr;
			s->___type_sub_class_restrain__SharedObjectRecycleable();
		}
	};
	ShareObjectPool();
	static int capacity;
	static ClassType** _pool;
	static int size;
	static std::mutex _mutex;

private:
	/**
	* @brief resize inner pool growing by twice
	* @warning this will copy old block and delete old
	*/
	static void ReSize()
	{
		auto pool = new ClassType*[capacity * 2];//
		memset(pool, 0, sizeof(ClassType*)* 2 * capacity);
		memcpy(pool, _pool, sizeof(ClassType*)* capacity);
		capacity *= 2;
		delete _pool;
		_pool = pool;
	}
	static void PreAlloc()
	{
		auto pool = _pool;
		for (int i = 0; i < OBJECT_POOL_DEFAULT_ALLOC_OBJECT_SIZE; i++)
		{
			pool[size] = new ClassType();
			++size;
		}
	}
public:
	/**
	* @brief  call this to new class who is the sub-class of ShareObjectRecycleable
	* @note if class size if smaller than OBJECT_POOL_MIN_SIZEOF will new otherwise will gen object from pool
	*/
	static share_ptr<ClassType, ThreadSafe> Create()
	{
		if (ThreadSafe)
		{
			ClassType * ret = nullptr;
			{
				std::lock_guard<std::mutex> locker(_mutex);
				static ShareObjectPool<ClassType, ThreadSafe>::Ctor<ClassType, ThreadSafe> ctor;//c11 compiler suport thread-safe
				if (size > 0 && sizeof(ClassType) >= OBJECT_POOL_MIN_SIZEOF)
				{
					--size;
					ret = (_pool[size]);
					_pool[size] = nullptr;
				}
			}
			if (!ret)
			{
				ret = new ClassType();
			}
			ret->ctor();
			return share_ptr<ClassType, ThreadSafe>(ret);
		}
		else
		{
			static ShareObjectPool<ClassType, ThreadSafe>::Ctor<ClassType, ThreadSafe> ctor;//c11 compiler suport thread-safe
			if (size > 0 && sizeof(ClassType) >= OBJECT_POOL_MIN_SIZEOF)
			{
				--size;
				ClassType* ret = (_pool[size]);
				_pool[size] = nullptr;
				ret->ctor();
				return  share_ptr<ClassType, ThreadSafe>(ret);
			}
			//ctor will be call in share_ptr::share_ptr();
			return  share_ptr<ClassType, ThreadSafe>();
		}
	}
	/**
	* @brief release object to the pool
	* @note this will not call manual ShareObjectRecycleable will call this function automatic
	* @note if sizeof class is smaller than OBJECT_POOL_MIN_SIZEOF will delete now otherwise will put into pool
	*/
	static void Release(ClassType* who)
	{
		if (!who)return;
		who->dtor();
		if (sizeof(ClassType) < OBJECT_POOL_MIN_SIZEOF)
		{
			delete who;
			return;
		}
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			if (size >= OBJECT_POOL_MAX_SIZE)
			{
				cout << capacity << " " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << " warnning Release out-of-size" << endl;
				delete who;
				return;
			}
			if (size >= capacity)
			{
				ReSize();
			}
			_pool[size] = who;
			++size;
		}
		else
		{
			if (size >= OBJECT_POOL_MAX_SIZE)
			{
				cout << capacity << " " << typeid(ObjectPool<ClassType, ThreadSafe>).name() << " warnning Release out-of-size" << endl;
				delete who;
				return;
			}
			if (size >= capacity)
			{
				ReSize();
			}
			_pool[size] = who;
			++size;
		}
	}
	/**
	* @brief  delete all objects in this pool
	*/
	static void Clear()
	{
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			if (size <= 0)return;
			for (int i = 0; i < size; i++)
			{
				if (_pool[i])
				{
					delete _pool[i];
					_pool[i] = nullptr;
				}
			}
			size = 0;
		}
		else
		{
			if (size <= 0)return;
			for (int i = 0; i < size; i++)
			{
				if (_pool[i])
				{
					delete _pool[i];
					_pool[i] = nullptr;
				}
			}
			size = 0;
		}
	}
	inline static int Size()
	{
		if (ThreadSafe)
		{
			std::lock_guard<std::mutex> locker(_mutex);
			return  size
		}
		else
		{
			return  size
		}
	}
	/**
	* @brief print current pool status for debug
	*/
	static	void PrintStatus()
	{
		int total = (sizeof(ClassType)* size);
		if (total < 1024)
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) << "B " << typeid(ShareObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
		else if (total < 1024 * 1024)
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) / 1024.0 << "KB " << typeid(ShareObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
		else
		{
			cout << "capacity:" << capacity << " size:" << size << " memeory:" << (sizeof(ClassType)* size) / 1024.0 / 1024.0 << "MB " << typeid(ShareObjectPool<ClassType, ThreadSafe>).name() << endl;
		}
	}
};
template<class ClassType, bool ThreadSafe>
ClassType**ShareObjectPool<ClassType, ThreadSafe>::_pool = new ClassType*[OBJECT_POOL_DEFAULT_ALLOC_SIZE];//
template<class ClassType, bool ThreadSafe>
int ShareObjectPool<ClassType, ThreadSafe>::size = 0;
template<class ClassType, bool ThreadSafe>
std::mutex ShareObjectPool<ClassType, ThreadSafe>::_mutex;
template<class ClassType, bool ThreadSafe>
int ShareObjectPool<ClassType, ThreadSafe>::capacity = OBJECT_POOL_DEFAULT_ALLOC_SIZE;




//T 只能是 SharedObjectRecycleable的子类
//12 bytes use in x86
//20 bytes use in x64
//ThreadSafe just mean ShareObjectPool not this class(share_ptr)
//this class is thread safe base-on std::shared_ptr
template<typename T, bool ThreadSafe = false>
class share_ptr
{
	struct __inner_ref_wrapper
	{
	};
public:
	//请勿随便使用该变量 除非你知道你在干什么
	T * raw = nullptr;//4 bytes
	//请勿随便使用该变量 除非你知道你在干什么
	std::shared_ptr<__inner_ref_wrapper> __ptr = nullptr;//8 bytes
	~share_ptr()
	{
		//thread-safe
		if (__ptr.use_count() == 1)//only self ref this
		{
			//如果编译报错 那么证明不是约束下的 子类关系 请确认
			ShareObjectPool<T, ThreadSafe>::Release((raw));
			//	ptr = NULL;
		}
	}
	inline	T *operator->()  const
	{
		return  this->raw;
	}
	share_ptr<T, ThreadSafe >& operator = (const share_ptr<T, ThreadSafe> & other)
	{
		this->__ptr = other.__ptr;
		this->raw = other.raw;
		return *this;
	}
	share_ptr() :
		__ptr(std::make_shared<share_ptr<T, ThreadSafe >::__inner_ref_wrapper>()), raw(new T())
	{
		//new T will call ctor 不在Pool里面调用ctor是为了减少一个share_ptr的 构造
		raw->ctor();
	}

	share_ptr(T*t) :
		__ptr(std::make_shared<share_ptr<T, ThreadSafe >::__inner_ref_wrapper>()), raw(t)
	{
	}
	share_ptr<T, ThreadSafe >(const share_ptr<T, ThreadSafe > &other) :
		__ptr(other.__ptr), raw(other.raw)
	{
	}
};
/*
该函数无意义 因为不允许 不和Pool一起使用
template<typename T, bool ThreadSafe = false>
inline share_ptr<T, ThreadSafe> make_share()
{
return share_ptr<T, ThreadSafe>();
}*/


//ThreadSafe just mean ObjectPool not this class(RawObjectRecycleable)
template<typename SubClassType, bool ThreadSafe = false>
class RawObjectRecycleable :public RawObject, public Recycleable
{
public:
	inline void Release()override
	{
		ObjectPool<SubClassType, ThreadSafe>::Release((SubClassType*)this);
	}
};
//ThreadSafe just mean ObjectPool not this class(RefObjectRecycleable)
template<typename SubClassType, bool ThreadSafe = false>
class RefObjectRecycleable :public RefObject, public Recycleable
{
public:
	inline	void Release() override
	{
		--referenct_count;
		if (referenct_count <= 0)
		{
			referenct_count = 0;
			ObjectPool<SubClassType, ThreadSafe>::Release((SubClassType*)this);
		}
	}
};

//这个 和 其他的不一样 用法比较特别 因为要支持pool
//创建请用ShareObjectPool<>::Create OR make_share
template<typename SubClassType>
class SharedObjectRecycleable : public Recycleable
{
public:
	//tag for class share_ptr T must is the sub-class of this class
	//泛型约束
	inline void ___type_sub_class_restrain__SharedObjectRecycleable()
	{
	}
};


#include<iostream>
#include "functional"
#include <chrono>
#include <thread>
using namespace std;
//cpp文件全部都是 测试代码 和 示例代码

class SharedObjectRecycleable111 :public SharedObjectRecycleable<SharedObjectRecycleable111>
{
public:
	SharedObjectRecycleable111()
	{
		cout << "SharedObjectRecycleable111:SharedObjectRecycleable111" << endl;
	}
	~SharedObjectRecycleable111()
	{
		cout << "~~SharedObjectRecycleable111:~SharedObjectRecycleable111 " << this << endl;
	}
	virtual void ctor()
	{

	}
	virtual void dtor()
	{
		xx = 10;
	}
	void print()
	{
		cout << "     " << (++xx) << endl;

	}
	int xx = 10;
	char sqdfqsd[30];//
};


class SharedObjectRecycleable222222 :public SharedObjectRecycleable<SharedObjectRecycleable222222>
{
public:
	SharedObjectRecycleable222222()
	{
		//		cout << "SharedObjectRecycleable222222:SharedObjectRecycleable222222" << endl;
	}
	~SharedObjectRecycleable222222()
	{
		//	cout << "~~SharedObjectRecycleable222222:~SharedObjectRecycleable222222 " << this << endl;
	}
	virtual void ctor()
	{

	}
	virtual void dtor()
	{
		xx = 10;
	}
	void print()
	{
		//	cout << "     " << (++xx) << endl;

	}
	int xx = 10;
	char sqdfqsd[10240000];//
};


class RefObject2222 :public RefObject
{
public:
	RefObject2222()
	{
		cout << "RefObject2222:RefObject2222" << endl;
	}
	~RefObject2222()
	{
		cout << "~~RefObject2222:~RefObject2222 " << this << endl;
	}
};


class RefObject1111 :public RefObject
{
public:
	RefObject1111()
	{
		cout << "RefObject1111:RefObject1111" << endl;
		this->img = new RefObject2222();//默认图片

	}
	~RefObject1111()
	{
		cout << "~~RefObject1111:~RefObject1111 " << this << endl;
		if (this->img)
		{
			this->img->Release();//计数-1
		}
	}
public:
	void SetImage(RefObject2222 * img)
	{
		if (this->img)
		{
			this->img->Release();//计数-1
		}
		img->Retain();//计数+1
		this->img = img;
	}
	RefObject2222 * img = nullptr;
};





class RefObjectRecycleable22222222 :public RefObjectRecycleable<RefObjectRecycleable22222222>
{
public:
	RefObjectRecycleable22222222()
	{
		cout << "RefObjectRecycleable22222222:RefObjectRecycleable22222222" << endl;
	}
	~RefObjectRecycleable22222222()
	{
		cout << "~~RefObjectRecycleable22222222:~RefObjectRecycleable22222222 " << this << endl;
	}
	void ctor() {};
	void dtor(){};
	char sqdfqsd[1024];//
};


class RefObjectRecycleable1111111111 :public RefObjectRecycleable<RefObjectRecycleable1111111111>
{
public:
	void ctor() {};
	void dtor(){};
	RefObjectRecycleable1111111111()
	{
		cout << "RefObjectRecycleable1111111111" << endl;
		this->img = ObjectPool<RefObjectRecycleable22222222>::Create();//默认图片

	}
	~RefObjectRecycleable1111111111()
	{
		cout << "~~RefObjectRecycleable1111111111 " << this << endl;
		if (this->img)
		{
			this->img->Release();//计数-1
		}
	}
	char sqdfqsd[1024];//
public:
	void SetImage(RefObjectRecycleable22222222 * img)
	{
		if (this->img)
		{
			this->img->Release();//计数-1
		}
		img->Retain();//计数+1
		this->img = img;
	}
	RefObjectRecycleable22222222 * img = nullptr;
};





class SharedObject111 :public SharedObject<SharedObject111>
{
public:
	SharedObject111()
	{
		cout << "SharedObject111:SharedObject111" << endl;
	}
	~SharedObject111()
	{
		cout << "~~SharedObject111:~SharedObject111 " << this << endl;
	}
};

class RawObjectRecycleable11111111 : public RawObjectRecycleable<RawObjectRecycleable11111111>
{
public:
	RawObjectRecycleable11111111()
	{
		cout << "RawObjectRecycleable11111111" << endl;
	}
	~RawObjectRecycleable11111111()
	{
		cout << "~~RawObjectRecycleable11111111 " << this << endl;
	}
	int x = 5;
	void print()
	{
		cout << "print" << endl;
	}
	void ctor() {};
	void dtor(){};

	char sss[1024];

};

class RawObjectRecycleable666666 : public RawObjectRecycleable<RawObjectRecycleable666666, true>
{
public:
	RawObjectRecycleable666666()
	{
		//	cout << "RawObjectRecycleable666666" << endl;
	}
	~RawObjectRecycleable666666()
	{
		//cout << "~~RawObjectRecycleable666666 " << this << endl;
	}
	int x = 5;
	void print()
	{
		cout << "print " << (++x) << endl;
	}
	void ctor() {};
	void dtor(){ x = 5; };

	char sss[10240];

};



#if _WIN32
#include "windows.h"
#include <WinBase.h>  
int  calculateMS(std::function<void()> processFunc)
{
	long long _value;
	LARGE_INTEGER freq, _start, _end;
	QueryPerformanceFrequency(&freq);
	QueryPerformanceCounter(&_start);

	processFunc();

	QueryPerformanceCounter(&_end);
	_value = (_end.QuadPart - _start.QuadPart) * 1000 / freq.QuadPart;

	return _value;
}



int   calculateUS(std::function<void()> processFunc)
{
	long long _value;
	LARGE_INTEGER freq, _start, _end;
	QueryPerformanceFrequency(&freq);
	QueryPerformanceCounter(&_start);

	processFunc();

	QueryPerformanceCounter(&_end);
	_value = (_end.QuadPart - _start.QuadPart) * 1000 * 1000 / freq.QuadPart;

	return _value;
}





void func_test_benchmark_share_pool()
{
	printf("%d   \r\n\n", calculateUS([=]()
	{
		for (int i = 0; i != 10000; i++)
		{
			auto s1 =
				ShareObjectPool< SharedObjectRecycleable111>::Create();
			auto s2 =
				ShareObjectPool< SharedObjectRecycleable111>::Create();
			auto s3 =
				ShareObjectPool< SharedObjectRecycleable111>::Create();
			auto s4 =
				ShareObjectPool< SharedObjectRecycleable111>::Create();


		}
	}));

	printf("%d   \r\n\n", calculateUS([=]()
	{
		for (int i = 0; i != 10000; i++)
		{
			auto s1 = make_shared<SharedObjectRecycleable111>();
			auto s2 = make_shared<SharedObjectRecycleable111>();
			auto s3 = make_shared<SharedObjectRecycleable111>();
			auto s4 = make_shared<SharedObjectRecycleable111>();


		}
	}));
	printf("%d   \r\n\n", calculateUS([=]()
	{
		for (int i = 0; i != 10000; i++)
		{
			auto s1 = new SharedObjectRecycleable111();
			delete s1;
			auto s2 = new SharedObjectRecycleable111();
			delete s2;
			auto s3 = new SharedObjectRecycleable111();
			delete s3;
			auto s4 = new SharedObjectRecycleable111();
			delete s4;

		}
	}));
	auto s11 =
		ShareObjectPool< SharedObjectRecycleable111>::Create();


	ShareObjectPool<SharedObjectRecycleable111>::Clear();
	ShareObjectPool< SharedObjectRecycleable111>::Clear();
}

#endif

//传递方法和 std::shared_ptr 一样
void func_test_share_pool_2(share_ptr<SharedObjectRecycleable111, false> obj)
{
	//添加了一个引用
	//引用为2
	obj->print();
	cout << obj.raw << endl;
}
//测试 ShareObjectPool  和example
void func_test_share_pool()
{
	{
		{
			auto obj1 = ShareObjectPool< SharedObjectRecycleable111>::Create();

			auto obj2 = obj1;//一个拷贝 和std::shared_ptr一样 直接传递对象即可
			obj1->print();
			cout << obj1.raw << endl;
		}
		//执行到这里 没有任何引用了 已经被 回收 Pool大小为1


		//obj1 是刚刚回收的对象 和上面的是同一个对象
		auto obj1 = ShareObjectPool< SharedObjectRecycleable111>::Create();
		obj1->print();
		cout << obj1.raw << endl;

		//pool大小为0  创建了一个新的对象
		auto obj2 = ShareObjectPool< SharedObjectRecycleable111>::Create();
		obj2->print();//引用为1
		cout << obj2.raw << endl;

		func_test_share_pool_2(obj2);//执行完成后引用为1了
		//由于pool为空 所以无效
		ShareObjectPool< SharedObjectRecycleable111>::Clear();
		cout << "-------" << endl;
	}
	//大小为2 被delete
	ShareObjectPool< SharedObjectRecycleable111>::Clear();
}

void func_test_ref_object()
{
	{
		RefObject1111 *obj = new RefObject1111;//计数1
		obj->Retain();//计数2

		obj->Release();//计数1
		obj->Release();//计数0 被delete



		RefObject1111 *obj1 = new RefObject1111;//计数1
		obj1->Release();//计数0 被delete


		RefObject1111 *obj2 = new RefObject1111;//计数1
		//obj2 泄露了
	}

	cout << "............0" << endl;
	{
		RefObject2222 *img = new RefObject2222;//计数1 图片资源

		RefObject1111*sprite = new RefObject1111;//计数1 图片拥有者

		sprite->SetImage(img);//--img计数2
		img->Release();//变量img的 作用域交出控制权 img计数1
		sprite->Release();//变量sprite 交出控制权 但是无其他引用 都被delete掉了
		//img sprite 被全部清理了
	}
}


void func_test_share_object()
{
	auto obj1 = std::make_shared<SharedObject111>();//ok create one

	std::shared_ptr<SharedObject111> obj0;// none ref

	{
		auto obj1 = std::make_shared<SharedObject111>();//ok create one
		{
			auto obj2 = obj1->shared_from_this();//create new from shared
			obj0 = obj2->shared_from_this();//create from obj2
			auto obj3 = obj1;//create from obj2

		}
	}

	{
		auto obj11 = std::make_shared<SharedObject111>();//ok create one
	}
	//obj11 has been delete
	cout << "1111" << endl;
}

void func_test_raw_object_pool()
{
	auto obj1 = ObjectPool<RawObjectRecycleable11111111>::Create();
	obj1->Release();


	auto obj2 = ObjectPool<RawObjectRecycleable11111111>::Create();
	obj2->Release();

	auto obj3 = ObjectPool<RawObjectRecycleable11111111>::Create();
	obj3->Release();

	cout << "111111111111" << endl;
	ObjectPool<RawObjectRecycleable11111111, false>::Clear();

}

void func_test_ref_object_pool()
{

	RefObjectRecycleable22222222 *obj = ObjectPool<RefObjectRecycleable22222222>::Create();//计数1
	cout << "  obj " << obj << endl;
	obj->Retain();//计数2

	obj->Release();//计数1
	obj->Release();//计数0 被 ObjectPool回收

	RefObjectRecycleable22222222 *obj1 = ObjectPool<RefObjectRecycleable22222222>::Create();//计数1
	cout << "  obj1 " << obj1 << endl;
	obj1->Release();//计数0 被 ObjectPool回收


	cout << "............0" << endl;

	RefObjectRecycleable1111111111 *obj2 = ObjectPool<RefObjectRecycleable1111111111>::Create();//计数1
	cout << "  obj2 " << obj2 << endl;
	cout << "  obj2 img " << obj2->img << endl;//this img is in old  object obj



	obj2->Release();//计数0 被 ObjectPool回收




	/*	RefObject1111 *obj1 = new RefObject1111;//计数1
	obj1->Release();//计数0 被delete


	RefObject1111 *obj2 = new RefObject1111;//计数1
	//obj2 泄露了
	}

	cout << "............0" << endl;
	{
	RefObject2222 *img = new RefObject2222;//计数1 图片资源

	RefObject1111*sprite = new RefObject1111;//计数1 图片拥有者

	sprite->SetImage(img);//--img计数2
	img->Release();//变量img的 作用域交出控制权 img计数1
	sprite->Release();//变量sprite 交出控制权 但是无其他引用 都被delete掉了
	//img sprite 被全部清理了


	*/

	cout << "............0" << endl;
	ObjectPool<RefObjectRecycleable22222222>::Clear();
}


void func_test_share_object_pool_thread_safe()
{
	for (int i = 0; i < 10; i++)
	{
		std::thread t([=]
		{
			int i = 300;

			while (--i>0)
			{


				auto s4 =
					ShareObjectPool< SharedObjectRecycleable222222, true>::Create();

				//	auto obj1 = ObjectPool<RawObjectRecycleable666666, true>::Create();
				//	cout << obj1 << endl;
				//	if (obj1)	obj1->Release();
				//		ObjectPool<RawObjectRecycleable666666, true>::Clear();
			}
			cout << "............thread exit" << endl;
		});
		t.detach();
	}
	this_thread::sleep_for(std::chrono::milliseconds(20));

	ShareObjectPool< SharedObjectRecycleable222222, true>::PrintStatus();

	ShareObjectPool< SharedObjectRecycleable222222, true>::Clear();
}

void func_test_raw_object_pool_thread_safe()
{
	for (int i = 0; i < 10; i++)
	{
		std::thread t([=]
		{
			int i = 3000;

			while (--i>0)
			{
				auto obj1 = ObjectPool<RawObjectRecycleable666666, true>::Create();
				obj1->Release();


				auto obj2 = ObjectPool<RawObjectRecycleable666666, true>::Create();
				obj2->Release();


			}
			cout << "............thread exit" << endl;
		});
		t.detach();
	}

	this_thread::sleep_for(std::chrono::milliseconds(20));

	auto obj1 = ObjectPool<RawObjectRecycleable666666, true>::Create();
	obj1->Release();


	ObjectPool< RawObjectRecycleable666666, true>::PrintStatus();

	ObjectPool< RawObjectRecycleable666666, true>::Clear();


}

static std::mutex  __mutex;
void __func_mutex()
{
	//	std::lock_guard<std::mutex> loc(__mutex);
	__mutex.lock();
	static int xx = 0;
	xx++;
	__mutex.unlock();
}

void func_test_raw_object_pool_thread_safe__bug_()
{
	for (int i = 0; i < 10; i++)
	{
		std::thread t([=]
		{
			int i = 30000;
			while (i>0)
			{
				//		std::this_thread::yield();
				//Sleep(1);// will reduce bug rate
				__func_mutex();//BUG when main function return static variable _mutex was destroy but sub-thread still use this.
				//mutex destroyed while busy
				//TODO fixed me
			}
			cout << "............thread exit" << endl;
		});
		t.detach();
	}
	this_thread::sleep_for(std::chrono::milliseconds(2000));

}

int main(int argc, char* argv[])
{
	func_test_raw_object_pool_thread_safe__bug_();

	//	func_test_raw_object_pool_thread_safe();
	//Sleep(10000000);// 20 second
	//exit(0);
	system("pause");


	return 0;
}

猜你喜欢

转载自my.oschina.net/kkkkkkkkkkkkk/blog/1790064