C++實現多執行緒物件記憶體池帶垃圾回收機制
阿新 • • 發佈:2019-02-05
#include <Windows.h> #include <iostream> #include <map> #include <string> #include <assert.h> #include <deque> #include <map> #include <set> typedef int s32; typedef unsigned int u32; typedef char c8; ////////////////////////////////////////////////////////////////////////// //1.因為存在gc記憶體垃圾回收與傳統物件池不同,特別適合對效能又要求並且對記憶體容量又要求的伺服器 //2.適合客戶端對效能和容量有要求 //3.臨時寫的難免有BUG見諒,但大體思想沒有問題 //鎖物件封裝 class LockObject { public: LockObject() { InitializeCriticalSection(&mLock); } ~LockObject() { DeleteCriticalSection(&mLock); } void Lock() { EnterCriticalSection(&mLock); } void UnLock() { LeaveCriticalSection(&mLock); } bool TryLock() { return TryEnterCriticalSection(&mLock); } private: LockObject(const LockObject &other) {} LockObject& operator = (const LockObject &other) {} private: CRITICAL_SECTION mLock; }; //鎖區域封裝 class ScopeLock { public: ScopeLock(CRITICAL_SECTION &lock) :mlock(lock) { EnterCriticalSection(&mlock); } ScopeLock(LockObject &lock) :mlock( reinterpret_cast<CRITICAL_SECTION&>(lock) ) { EnterCriticalSection(&mlock); } ~ScopeLock() { LeaveCriticalSection(&mlock); } private: ScopeLock( const ScopeLock &other) :mlock(other.mlock) {} ScopeLock& operator = (const ScopeLock &other) {} private: CRITICAL_SECTION &mlock; }; //物件池介面 typedef interface IObjectPool { virtual void gc(bool IsForce) = 0; }* IObjectPoolPtr; //物件池 template< typename T > class ObjectPool : public IObjectPool { public: ObjectPool(u32 ChunkSize = 32) { mChunkSize = ChunkSize; } ~ObjectPool() { gc(true); } T* New() { ScopeLock LockBody(mLock); if(mFreeBlocks.empty()) { _Malloc(); } if(mFreeBlocks.empty()) { assert(false); return nullptr; } auto p = mFreeBlocks.front(); mFreeBlocks.pop_front(); new(p)T(); return p; } void Delete(T* p) { ScopeLock LockBody(mLock); p->~T(); mFreeBlocks.push_back(p); } //外部應該定時呼叫這個函式,自動回收記憶體 virtual void gc(bool IsForce) { ScopeLock LockBody(mLock); auto IsCangc = true; std::set<T*> FreeBlocks(mFreeBlocks.begin(), mFreeBlocks.end()); T* pT = nullptr; for(auto i = mChunks.begin(); i != mChunks.end();) { for(auto j = 0; j < i->first; ++j) { pT = i->second + j; if(FreeBlocks.end() == FreeBlocks.find( pT ) ) { if(IsForce) { pT->~T(); } else { IsCangc = false; break; } } } if(IsCangc) { for(auto j = 0; j < i->first; ++j) { FreeBlocks.erase(j + i->second); } free(i->second); i = mChunks.erase(i); mChunkSize >>= 1; } else { IsCangc = true; ++i; } } mFreeBlocks.assign( FreeBlocks.begin(), FreeBlocks.end() ); } private: void _Malloc() { const auto pMemory = reinterpret_cast<T*>( malloc( mChunkSize * sizeof( T ) ) ); if(nullptr == pMemory) { assert(false); return; } const auto Insert = mChunks.insert( std::make_pair( mChunkSize, pMemory ) ); if(false == Insert.second) { assert(false); free(pMemory); return; } for(auto i = 0; i < mChunkSize; ++i) { mFreeBlocks.push_back(pMemory + i); } mChunkSize <<= 1; } private: std::map<u32,T*> mChunks; std::deque<T*> mFreeBlocks; u32 mChunkSize; LockObject mLock; }; //物件池工廠,可以自定義一些巨集定義,實現對整個物件池的管理 class ObjectPoolFactory { public: ~ObjectPoolFactory() { ScopeLock LockBody(mLock); for(auto i = mObjectPools.begin(); i != mObjectPools.end(); ++i) { delete i->second; i->second = nullptr; } mObjectPools.clear(); } //單件例項 static ObjectPoolFactory& GetInstance() { static ObjectPoolFactory Instance; return Instance; } template< typename T > ObjectPool<T>* CreateObjectPool(c8 *pName) { if(nullptr == pName) { assert(false); return nullptr; } ScopeLock LockmObjectPools(mLock); const auto Search = mObjectPools.find(pName); if(mObjectPools.end() == Search) { const auto Insert = mObjectPools.insert(std::make_pair(pName, new ObjectPool<T>())); if(false == Insert.second) { assert(false); return nullptr; } return (ObjectPool<T>*)Insert.first->second; } return (ObjectPool<T>*)Search->second; } //垃圾回收 void gc() { ScopeLock LockBody(mLock); for(auto i = mObjectPools.begin(); i != mObjectPools.end(); ++i) { i->second->gc(false); } } //關閉無用的構造方法 private: ObjectPoolFactory() {} ObjectPoolFactory(const ObjectPoolFactory &other) {} ObjectPoolFactory& operator =(const ObjectPoolFactory &other) {} private: LockObject mLock; std::map<std::string, IObjectPoolPtr> mObjectPools; }; int main() { auto &Factory = ObjectPoolFactory::GetInstance(); struct ABC { int a; }; auto a = Factory.CreateObjectPool<ABC>("ABC"); // auto x = a->New(); a->Delete(x); return 0; }