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

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

 

来源:http://www.cppblog.com/PeakGao/archive/2007/10/28/35360.html


今天在看ACE内存分配的时候(太多,没看完),发现分配策略不全,我想实现一个能缓存,高效,内存总量不限的分配策略用于对 ACE_Message_Block对象的缓存,虽然ACE_Message_Block支持为它设置三种分配器,一个是对ACE_Message_Block对象本身message_block_allocator_,一个是对ACE_Data_Block本身data_block_allocator_,还有一个是对ACE_Data_Block的数据缓冲区的分配器allocator_strategy_,但是感觉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出一个缓冲链,每个缓冲链为
        <BlockCount>个大小为<BlockSize>的内存块,缓冲链之间建立链表关
        系。

        优点:
        1、不存在realloc,缓冲地址固定不变;
        2、缓冲池大小由小变大,动态增长,不是一开始就分配一个超大的内
        存,真正按需分配;
        3、支持锁策略,目前用的ACE的锁,可以很方便的改为其他的锁策略;
        4、支持FreeList,高效;

        缺点:
        1、分配的对象在长时间不用时不能智能释放

        要求:
        1、每个块的大小必须大于等于sizeof(CacheNode)

        示例:
        typedef CachePool<ACE_SYNCH_NULL_MUTEX>        CachePool_NullMutex; // 单线程
        typedef CachePool<ACE_SYNCH_MUTEX>            CachePool_Mutex;     // 多线程
        
        CachePool_Mutex pool(1024, 256)
        void* buf = pool.alloc();
        pool.free(buf);
        pool.clear();

    */
    template<class _ACEMutex>
    class CachePool
    {
protected:
        /// 缓冲链: Head + cache1 + cache2 + cacheN (N=BlockCount)
        struct CacheChain
        {
            CacheChain* _Next;

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

            inline static CacheChain* create(CacheChain*& head, size_t blockSize, size_t blockCount)
            {
                CacheChain* p = (CacheChain*) new char[sizeof(CacheChain) + blockCount * blockSize];
                p->_Next = head;
                return head = p;
            }

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

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

        size_t            _BlockSize;        /// 数据块的字节大小
        size_t            _BlockCount;    /// 每次连续分配的块数
        CacheChain*        _ChainList;        /// 每次分配的缓冲链
        CacheNode*        _FreeNode;        /// 当前空闲节点
        _ACEMutex*        _Mutex;            /// 线程互斥体
        bool            _DeleteMutex;    /// 是否在析构的时候删除互斥体

    public:
        CachePool()
            : _BlockSize(0), _BlockCount(0), _ChainList(0), _FreeNode(0), _Mutex(0), _DeleteMutex(false)
        {
        }

        CachePool(size_t blockSize, size_t blockCount, _ACEMutex* mutex = 0)
            : _ChainList(0), _FreeNode(0), _Mutex(mutex)
        {
            create(blockSize, blockCount, mutex);
        }

        ~CachePool()
        {
            if (_Mutex != 0 && _DeleteMutex)
            {
                clear();

                delete _Mutex;
                _Mutex = 0;
                _DeleteMutex = false;
            }
        }

        /// 清除所有的内存空间
        void clear()
        {
            ACE_GUARD(_ACEMutex, ace_mon, *_Mutex);

            if (_ChainList)
            {
                _ChainList->free();
                _ChainList = 0;
                _FreeNode = 0;
            }
        }

        /// 初始化参数
        void create(size_t blockSize, size_t blockCount, _ACEMutex* mutex = 0)
        {
            _BlockSize = blockSize;
            _BlockCount = blockCount;

            assert(_BlockCount >= 1);
            assert(sizeof(CacheNode) <= _BlockSize);

            if (_DeleteMutex && _Mutex)
                delete _Mutex;

            if (mutex != 0)
            {
                _Mutex = mutex;
                _DeleteMutex = false;
            }
            else
            {
                _Mutex = new _ACEMutex();
                _DeleteMutex = true;
            }
        }

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

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

        /// 分配一个块内存
        void* alloc()
        {
            assert(_BlockCount >= 1);
            assert(sizeof(CacheNode) <= _BlockSize);
            assert(_Mutex != NULL);

            ACE_GUARD_RETURN(_ACEMutex, ace_mon, *_Mutex, NULL);

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

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

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

                // 建立连接关系
                for (int i=(int)_BlockCount-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)
        {
            ACE_GUARD(_ACEMutex, ace_mon, *_Mutex);

            if (block != 0)
            {
                CacheNode* node = (CacheNode*)block;
                node->_Next = _FreeNode;
                _FreeNode = node;
            }
        }
    };



    /**
        对象池
        在CachePool的基础上,增加了对象的构造和析构
        为了更好扩充,没有采取继承而是包含的作法
    */
    template<class T, class _ACEMutex>
    class ObjectPool
    {
    protected:
        typedef CachePool<_ACEMutex>    _CachePool;
        _CachePool    _Pool;

    public:
        ObjectPool()
        {
        }

        ObjectPool(size_t blockCount, _ACEMutex* mutex = 0)
        {
            _Pool.create(sizeof(T), blockCount, mutex);
        }

        /// 清除分配的内存
        void clear()
        {
            _Pool.clear();
        }

        /// 初始化参数
        void create(size_t blockCount, _ACEMutex* mutex = 0)
        {
            _Pool.create(sizeof(T), blockCount, mutex);
        }

        /// 获取连续分配的对象的数目
        size_t getObjectCount() const
        {
            return _Pool.getBlockCount();
        }

        /// 创建对象的内存空间,但是没有进行构造,用户可以自行进行定制的构造
        T* alloc()
        {
            void* obj = _Pool.alloc();
            ::new (obj) T(/* not args */); // 进行默认构造
            return (T*)obj;
        }

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

} // namespace om

#endif // OM_MEMPOOLT_H

 

[审核人]初学MPEG

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

Please Login (or Sign Up) to leave a comment