C++ Slab分配器的实现

2940阅读 5评论2012-05-03 datao0907
分类:C/C++

C++Slab分配器主要基于C语言的分配器之上 ,进行包装调用形成,而在调用C语言接口之前,需要进行重载C++中的new,delete函数接口(静态函数形式提供),也就是通过模板提供一层接口,这样在进行分配时,顺序如下:

1.调用重载的new接口

2.调用具体类new接口

析构时刚好顺序相反,具体的封装类如下:

1.首先提供一层对C语言接口封装的的类:


点击(此处)折叠或打开

  1. template <typename T>
  2. class _Slab
  3. {
  4.     //protected:
  5.     //friend class Singleton< _Slab<T> >;
  6. public:
  7.     _Slab()
  8.     {
  9.         
  10.         std::cout <<"T:"<<typeid(T).name()<<" size:"<<sizeof(T)<<std::endl;
  11.         if((m_pSlabCache = umem_cache_create(typeid(T).name(),sizeof(T),ALIGN4,SLAB_NOSLEEP,NULL,NULL)) == NULL)
  12.             std::cout <<"Create Slab Error"<<std::endl;
  13.     }
  14.     
  15.     ~_Slab()
  16.     {
  17.         umem_cache_destroy(m_pSlabCache);
  18.     }

  19.     void* alloc(std::size_t size)
  20.     {
  21.         return umem_cache_alloc(m_pSlabCache);
  22.     }
  23.     
  24.     void dealloc(void *p,std::size_t size)
  25.     {
  26.         umem_cache_free(m_pSlabCache,p);
  27.     }
  28.     
  29. private:
  30.     umem_cache_t* m_pSlabCache;
  31. };

2.在此基础上提供一层针对new/delete的静态模板类接口:


  1. template <typename T>
  2. class Slab
  3. {
  4. public:
  5.     static void* operator new(std::size_t size)
  6.     {
  7.         std::cout <<"operator new:"<<size<<std::endl;
  8.         return Singleton < _Slab <T> >::getInstance()->alloc(size);
  9.     }
  10.     static void operator delete(void *p,std::size_t size)
  11.     {
  12.         std::cout << "delete" << std::endl;
  13.         Singleton< _Slab <T> >::getInstance()->dealloc(p,size);
  14.     }
  15.         
  16.     virtual ~Slab()
  17.     {
  18.     }
  19. };

3.上面的封装类采用了单例的方式提供,具体实现如下:


  1. template <typename T>
  2. class Singleton
  3. {
  4. public:
  5.     static T* getInstance()
  6.     {
  7.         static T t;
  8.         std::cout << typeid(T).name() << endl;
  9.         return &t;
  10.     }
  11. private:
  12.     Singleton()
  13.     {
  14.     }
  15.     Singleton(const Singleton&);
  16.     Singleton& operator=(const Singleton &);
  17.     ~Singleton()
  18.     {
  19.     }
  20. };

4.测试程序如下


  1. #include <iostream>
  2. using namespace std;
  3. #include "Slab.h"
  4. class A:public Slab<A>
  5. {
  6. public:
  7.     A(int s):size(s)
  8.     {
  9.         std::cout << "class A"<<std::endl;
  10.     }
  11.     
  12.     ~A()
  13.     {
  14.         std::cout << "class ~A"<<std::endl;
  15.     }
  16.    
  17.     void show()
  18.     {
  19.         std::cout <<"size:"<<size<<std::endl;
  20.     }
  21.   
  22. private:
  23.     int size;
  24. };

  25. int main(void)
  26. {
  27.     //Slab<A> *pA = new Slab<A>();
  28.     A *pA = new A(19);
  29.     
  30.     pA->show();
  31.     
  32.     delete pA;
  33.     
  34.     return 0;
  35. }

在编译时,gcc编译C语言中的slab文件:

  1. gcc -c slab.c -g

编译测试接口:

  1. g++ test_slab.cpp slab.o -g -lpthread

运行结果如下:


  1. operator new:8
  2. T:1A size:8
  3. 5_SlabI1AE
  4. class A
  5. size:19
  6. class ~A
  7. delete
  8. 5_SlabI1AE

这样就实现了一个面向对象的内存分配功能,这里只能针对某一类型的对象分配且内存大小小于4KB的对象.

完整原代码在这里:


上一篇:select 系统调用分析
下一篇:select 机制分析(二)

文章评论