支持HW团队,就支付宝领取下面的红包吧! (打开支付宝就能领取!er1OEj73Uj), (打开支付宝收索“516503473”), 你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

Login or Sign up | Validate
| Search
HelloWorld论坛 : > 计算机科学、技术、教学> 编程专题> 开源免费项目> [转]基于ACE实现的一个内存池-续篇
 
 
 
 
类别:ACE 阅读:5747 评论:0 时间:April 11, 2012, 11:24 a.m. 关键字: ACE 内存

 

来源:http://www.cppblog.com/PeakGao/archive/2007/10/29/35435.html
针对上篇文章《基于ACE实现的一个内存池 》,今天我进行了改版,实之更加方便和合理,代码如下:
// MemPoolT.h

/**
 *    @date 2007.10.25
 *  @author PeakGao <peakgao163@163.com>
 */
 #ifndef OM_MEMPOOLT_H
#define OM_MEMPOOLT_H

#include <assert.h>
#include <ace/guard_t.h>
#include <ace/global_macros.h>

namespace om{

    /**
        缓冲池

        缓存池采取2维内存缓冲机制,每次new出一个缓冲链,每个缓冲链为
        <GrowBlockCount>个大小为<BlockSize>的内存块,缓冲链之间建立链表关
        系。

        优点:
        1、缓冲池大小由小变大,动态增长,不是一开始就分配一个超大的内
        存,真正按需分配;
        2、不存在realloc,缓冲地址固定不变;
        3、支持FreeList,高效;

        缺点:
        1、分配的对象在长时间不用时没有实现智能释放,以后有需要再改

        要求:
        1、每个块的大小必须大于等于sizeof(Node),32位系统上面是4字节

        示例:
        @code
        class MyObj
        {
        public:
            MyObj()
            {
                std_out<<ACE_TEXT("MyObj::MyObj()")<<std_endl;
            }
            ~MyObj()
            {
                std_out<<ACE_TEXT("MyObj::~MyObj()")<<std_endl;
            }
            void foo()
            {
                std_out<<ACE_TEXT("MyObj::foo()")<<std_endl;
            }
            int dummy; 
        };

        void test()
        {
            using namespace om;
            typedef CachePoolWithLock<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> >            CachePool_Lock;

            CachePool p1;
            p1.create(1024, 256);
            void* pp1 = p1.alloc();
            p1.free(pp1);
            p1.clear();

            CachePool_Lock p2(7, 256);
            void* pp2 = p2.alloc();
            p2.free(pp2);
            p2.clear();


            ObjectPool<MyObj, CachePool_Lock>    pool(128);
            MyObj* o = pool.alloc();
            o->foo();
            pool.free(o);
            pool.clear();
        }
        @endcode
    */

    #define BYTE_ALIGN_8    /// 是否支持块尺寸8字节对齐的开关宏


    /**
        缓存池
        这里只实现逻辑,不考虑线程安全,线程安全的版本见下面的CachePoolWithLock模版
    */
    class CachePool
    {
    protected:

        /// 缓冲链: Head + cache1 + cache2 + cacheN (N=BlockCount)
        struct Chain
        {
            Chain* _Next;

            void* data() { return this + 1; }

            inline static Chain* create(Chain*& head, size_t blockSize, size_t blockCount)
            {
#if defined(BYTE_ALIGN_8)
                blockSize = blockSize ? ((blockSize + 7) & ~7) : 8; // 8字节对齐
#endif
                Chain* p = (Chain*) new char[sizeof(Chain) + blockCount * blockSize];

                p->_Next = head;
                return head = p;
            }

            void free()
            {
                Chain* p = this;
                while (p)
                {
                    char* buf = (char*)p;
                    Chain* next = p->_Next;
                    delete[] buf;
                    p = next;
                }
            }
        };


        /// 空闲对象节点,仅仅在空闲对象中有效
        struct Node
        {
            Node* _Next;
        };


        size_t    _BlockSize;            /// 数据块的字节大小
        size_t    _GrowBlockCount;    /// 每次连续分配的块数
        Chain*    _ChainList;            /// 每次分配的缓冲链
        Node*    _FreeNode;            /// 当前空闲节点

    public:
        /// 默认构造,注意必须调用create方法初始化参数
        CachePool()
            : _BlockSize(0), _GrowBlockCount(0), _ChainList(0), _FreeNode(0)
        {
        }

        CachePool(size_t blockSize, size_t growBlockCount)
            : _ChainList(0), _FreeNode(0)
        {
            create(blockSize, growBlockCount);
        }

        ~CachePool()
        {
            clear();
        }

        /// 清除所有的内存空间
        void clear()
        {
            if (_ChainList)
            {
                _ChainList->free();
                _ChainList = 0;
                _FreeNode = 0;
            }
        }

        /// 初始化参数
        void create(size_t blockSize, size_t growBlockCount)
        {
            _BlockSize = blockSize;
            _GrowBlockCount = growBlockCount;

            assert(_GrowBlockCount >= 1);
            assert(_BlockSize >= sizeof(Node));
        }

        /// 获取块的大小
        size_t getBlockSize() const
        {
            return _BlockSize;
        }

        /// 获取连续分配的块的数目
        size_t getGrowBlockCount() const
        {
            return _GrowBlockCount;
        }

        /// 分配一个块内存
        void* alloc()
        {
            assert(_GrowBlockCount >= 1);
            assert(_BlockSize >= sizeof(Node));

            if (_FreeNode == 0)
            {
                // 分配另一个数据链
                Chain* newChain = Chain::create(_ChainList, _BlockSize, _GrowBlockCount);

                Node* node = (Node*)newChain->data();

                // 定位到最后一个节点
                (char*&)node += _BlockSize * (_GrowBlockCount - 1);

                // 建立连接关系
                for (int i=(int)_GrowBlockCount-1; i>=0; i--, (char*&)node -= _BlockSize)
                {
                    node->_Next = _FreeNode;
                    _FreeNode = node;
                }
            }

            assert(_FreeNode != 0);

            void* block = (void*)_FreeNode;
            _FreeNode = _FreeNode->_Next;

            return block;
        }

        /// 释放块内存
        void free(void* block)
        {
            if (block != 0)
            {
                Node* node = (Node*)block;
                node->_Next = _FreeNode;
                _FreeNode = node;
            }
        }
    };




    /** 
        支持锁策略的缓存池,目前用的ACE的锁,可以很方便的改为其他的锁策略
        比如_ACELOCK可以为锁对象ACE_Lock_Adapter<ACE_SYNCH_MUTEX>,也可以
        直接用互斥体如ACE_SYNCH_NULL_MUTEX
    */
    template<class ACELOCK>
    class CachePoolWithLock : public CachePool
    {
    protected:
        ACELOCK        _Lock;            /// 锁

    public:
        CachePoolWithLock()
        {
        }

        CachePoolWithLock(size_t blockSize, size_t growBlockCount)
            : CachePool(blockSize, growBlockCount)
        {
        }

        /// 清除所有的内存空间
        void clear()
        {
            ACE_GUARD(ACELOCK, ace_mon, _Lock);
            CachePool::clear();
        }

        /// 分配一个块内存
        void* alloc()
        {
            ACE_GUARD_RETURN(ACELOCK, ace_mon, _Lock, NULL);
            return CachePool::alloc();
        }

        /// 释放块内存
        void free(void* block)
        {
            ACE_GUARD(ACELOCK, ace_mon, _Lock);
            CachePool::free(block);
        }
    };

    /**
        对象池
        在缓冲池的基础上,增加了对象的构造和析构为了更好扩充,模版参数直接传入缓冲池类型,可
        以是上面的CachePool、CachePoolWithLock,也可以是用户自定义的缓冲池,但必须符合调用规范
    */
    template<class T, class CachePoolStrategy>
    class ObjectPool : public CachePoolStrategy
    {
    protected:
        typedef CachePoolStrategy _Base;

    public:
        ObjectPool()
        {
        }

        ObjectPool(size_t growBlockCount)
            : _Base(sizeof(T), growBlockCount)
        {
        }

        /// 初始化参数
        void create(size_t growBlockCount)
        {
            _Base::create(sizeof(T), growBlockCount);
        }

        /// 创建对象的内存空间,但是没有进行构造,用户可以自行进行定制的构造
        T* alloc()
        {
            void* obj = _Base::alloc();
            ::new (obj) T(); // 只提供了采用默认构造的方式
            return (T*)obj;
        }

        /// 释放对象
        void free(T* obj)
        {
            if (obj != 0)
            {
                obj->~T();
                _Base::free(obj);
            }
        }
    };

} // namespace om

#endif // OM_MEMPOOLT_H

 

[审核人]初学MPEG

个人签名--------------------------------------------------------------------------------

Please Login (or Sign Up) to leave a comment