23 Mayıs 2015 Cumartesi

boost pool

Giriş
Sınıfları Boost dokümantasyonunun tersine sıralayacağım. pool_alloc STL veriyapıları ile kulllanılır. pool sınıfı malloc gibi çalışır. object_pool ise bir listeye doldurulmuş nesneler gibi düşünülebilir.

pool_alloc sınıfı
pool_allocator vector gibi büyük bellek alanları gerektiren vector,dequeue, string sınıfları ile kullanılır.
fast_pool_allocator ise list, set, map gibi düğümlerler çalışan sınıflar ile kullanılır. Şöyle kullanırız.
typedef std::map<
    int,
    int,
    less<int>,
    boost::pool_allocator<pair<const int, int> >
    > 
    MyMyapType;
fast_pool_allocator muadili için şu yazıya da bakılabilir.

pool sınıfı
malloc gibi çalışır. pool sınıfının kaç byte bellek alanı vereceği ve ilk büyüklüğü constructor metodu ile ayarlanır. İmzası şöyledir.
explicit pool(const size_type nrequested_size,const size_type nnext_size = 32)
Mesela 32 byte'lık bellek döndüren 64 chunk şöyle yaratılır.
boost::pool<> p(32, 64);

object_pool sınıfı
Yaratma
Sınıf şöyle tanımlanır.
boost::object_pool< MyClass > mypool;
construct metodu
Yeni bir nesne yaratmak için şöyle yapılır. Nesnemin constructor metoduna 3 taneye kadar parametre geçebilirim. Eğer daha fazla parametre geçmek istersem derleyici şöyle bir hata verir.
'boost::object_pool<T>::construct' : function does not take 4 arguments
Construct metodu eğer havuzda nesne kalmamışsa, yeni bir chunk belleği yaratır.
MyClass *p = mypool.construct(param1,param2);
Eğer istenirse template kullanan şöyle bir ObjectFactory yazılabilir.
template<typename TType = T, typename... TArgs> 
inline TType* create(TArgs&&... mArgs)
{
  return m_tpPool->construct(mArgs...);
}
construct metodu ve shared_ptr
Constructor metodu raw pointer döner. shared_ptr dönsün istiyorsak şöyle yaparız.
class ClassFactory
{
    boost::object_pool<YourClass> allocator;
public:
    boost::shared_ptr<YourClass> create()
    {
        return boost::shared_ptr<YourClass>(
            allocator.construct(),
            boost::bind(&ClassFactory::destroy, this, _1) );
    }

    void destroy(YourClass* pointer)
    {
        allocator.destroy(pointer);
    }
};
destroy metodu
Nesnenin destructor'ı çağırılır ama nesnenin kullandığı bellek alanı havuza geri döner.
inline void destroy(T* mObj) 
{ 
  m_tpPool->destroy(mObj);
}
free metodu
Nesnenin destructor'ı çağrılmaz ama nesne bellek havuzuna geri döner.

Thread Safe Pool
Bu sınıf thread safe değildir. Thread safe yapmak için mutex ile wrap etmek gerekir.
template <typename T>
class ObjectFactory 
{
    boost::object_pool<T>   m_Pool;
    boost::mutex            m_PoolMutex;

public:

    template<typename TType = T, typename... TArgs> 
    inline TType* create(TArgs&&... mArgs)
    {
        boost::unique_lock<boost::mutex> scoped_lock(m_PoolMutex);
        return m_Pool.construct(mArgs...);
    }

    inline void destroy(T* mObj) 
    { 
        boost::unique_lock<boost::mutex> scoped_lock(m_PoolMutex);
        m_Pool.destroy(mObj); 
    }

};



Hiç yorum yok:

Yorum Gönder