zoukankan      html  css  js  c++  java
  • object pool

    这是一个简单易用的对象池,很多系统对资源的访问快捷性及可预测性有严格要求,列入包括网络连接、对象实例、线程和内存。而且还要求解决方案可扩展,能应付存在大量资源的情形。

    object pool针对特定类型的对象循环利用,这些对象要么创建开销巨大,要么可创建的数量有限。而且在pool中的对象需要做到无状态。

    如何使用

    utility::object_pool_t<int> pool1([]()
    {
    return std::make_shared<int>(10);
    });

    {
    auto t = pool1.get();
    }

    指定类型,创建一个pool对象,同时提供创建对象函数。

    获取接口get,返回一个std::shared_ptr<T>对象,在该对象析构时自动返回到pool中,不需要额外的释放接口

    实现

    #ifndef __UTILITY_OBJECT_POOL_HPP
    #define __UTILITY_OBJECT_POOL_HPP


    #include <memory>
    #include <list>
    #include <functional>
    #include <cstdint>


    namespace utility {

    template < typename T >
    struct object_pool_traits_t;


    template < typename T, typename AllocatorT >
    struct object_pool_traits_t<std::list<std::shared_ptr<T>, AllocatorT>>
    {
    typedef std::shared_ptr<T> value_t;

    static value_t pop(std::list<value_t, AllocatorT> &l)
    {
    if( l.empty() )
    {
    return value_t();
    }
    else
    {
    value_t val = l.front();
    l.pop_front();
    return val;
    }
    }


    static void push(std::list<value_t, AllocatorT> &l, value_t && val)
    {
    l.push_back(std::move(val));
    }


    template < typename HandlerT >
    static void for_each(std::list<value_t, AllocatorT> &l, const HandlerT &handler)
    {
    std::for_each(l.cbegin(), l.cend(), handler);
    }


    static std::uint32_t size()
    {
    return l.size();
    }
    };



    template <
    typename T,
    typename C = std::list<std::shared_ptr<T>>
    >
    struct object_pool_t
    {
    typedef std::shared_ptr<T> value_t;
    typedef C queue_t;
    typedef std::shared_ptr<queue_t> pool_t;

    typedef std::function<value_t()> create_handler_t;
    static_assert(std::is_same<value_t, typename queue_t::value_type>::value, "container value_type must be std::shared_ptr<T> type");

    create_handler_t create_handler_;
    pool_t pool_;


    object_pool_t(const create_handler_t &create_handler)
    : pool_(std::make_shared<queue_t>())
    , create_handler_(create_handler)
    {
    if( create_handler_ == nullptr )
    create_handler_ = []()->value_t{ return std::make_shared<value_t::element_type>(); };
    }


    template < typename AllocatorT = std::allocator<char> >
    value_t get(const AllocatorT &allocator = AllocatorT())
    {
    value_t obj = object_pool_traits_t<queue_t>::pop(*pool_);
    if( !obj )
    obj = create_handler_();

    return std::shared_ptr<T>(obj.get(),
    [=](T *) mutable
    {
    object_pool_traits_t<queue_t>::push(*pool_, std::move(obj));
    }, allocator);
    }


    value_t raw_aciquire()
    {
    value_t obj = object_pool_traits_t<queue_t>::pop(*pool_);
    if( !obj )
    obj = create_handler_();

    return obj;
    }


    void raw_release(value_t &&val)
    {
    object_pool_traits_t<queue_t>::push(*pool_, std::move(val));
    }


    void for_each(const std::function<void(const value_t &)> &handler)
    {
    object_pool_traits_t<queue_t>::for_each(*pool_, handler);
    }


    std::uint32_t size() const
    {
    return object_pool_traits_t<queue_t>::size(*pool_);
    }
    };
    }

    #endif

    如何扩展

    1. 先扩展pool容器

    namespace utility  {

    template < >
    struct object_pool_traits_t<tbb::concurrent_bounded_queue<std::shared_ptr<int>>>
    {
    typedef std::shared_ptr<int> value_t;
    typedef tbb::concurrent_bounded_queue<value_t> container_t;


    static value_t pop(container_t &l)
    {
    value_t v;
    if( !l.try_pop(v) )
    return std::make_shared<int>();

    return v;
    }

    static void push(container_t &l, value_t && val)
    {
    l.push(val);
    }
    };

    }
    2. 定义类
    utility::object_pool_t<int, tbb::concurrent_bounded_queue<std::shared_ptr<int>>> pool2([]()
    {
    return std::make_shared<int>(1);
    });
    3. 获取资源
    {
    auto t = pool2.get(tbb::tbb_allocator<char>());
    }

    {
    auto n = pool2.raw_aciquire();
    *n = 12;
    pool2.raw_release(std::move(n));
    }


    over
  • 相关阅读:
    二进制位运算
    Leetcode 373. Find K Pairs with Smallest Sums
    priority_queue的用法
    Leetcode 110. Balanced Binary Tree
    Leetcode 104. Maximum Depth of Binary Tree
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 64. Minimum Path Sum
    Leetcode 63. Unique Paths II
    经典的递归练习
    案例:java中的基本排序
  • 原文地址:https://www.cnblogs.com/yu-yu/p/3329679.html
Copyright © 2011-2022 走看看