【CPP】固定大小内存池

程序运行时,通常会频繁地进行内存的分配和释放操作。传统的内存分配方式(如使用new和delete运算符)可能会导致内存碎片的产生,并且每次分配和释放内存都有一定的时间开销。内存池通过在程序启动时一次性分配一大块内存或一次性分配多个对象备用,然后在需要时从使用这些内存。当程序使用完内存后,将其归还给内存池,而不是直接释放回操作系统,以此来提高内存分配的效率并减少内存碎片。

#ifndef MEMORY_POOL_HPP_
#define MEMORY_POOL_HPP_

#include <condition_variable>
#include <list>
#include <memory>
#include <queue>
#include <type_traits>
#include <utility>

#if __cplusplus < 201103L
#error "This program requires C++11 or a later version to compile."
#elif __cplusplus < 201703L
#include <mutex>
#else
#include <shared_mutex>
#endif

template <typename ElementType>
class MemoryPool final {
  template <typename T, typename = void>
  struct HasReset : std::false_type {};

  template <typename T>
  struct HasReset<T, std::void_t<decltype(std::declval<T>().Reset())>> : std::true_type {};

  static_assert(HasReset<ElementType>::value, "T must has Reset() function");

#if __cplusplus < 201703L
  using mutex       = std::mutex;
  using lock_guard  = std::lock_guard<std::mutex>;
  using unique_lock = std::lock_guard<std::mutex>;
#else
  using mutex       = std::shared_mutex;
  using lock_guard  = std::lock_guard<std::shared_mutex>;
  using unique_lock = std::lock_guard<std::shared_mutex>;
#endif

 public:
  using SharedPtr = std::shared_ptr<MemoryPool>;
  using UniquePtr = std::unique_ptr<MemoryPool>;

 private:
  explicit MemoryPool(const std::size_t capacity) : capacity(capacity) {}

 public:
  MemoryPool(const MemoryPool &)            = delete;
  MemoryPool(MemoryPool &&)                 = delete;
  MemoryPool &operator=(const MemoryPool &) = delete;
  MemoryPool &operator=(MemoryPool &&)      = delete;

  ~MemoryPool() {
    lock_guard lck(mu);
    for (auto *item : this->itemAll) {
      delete item;
    }
    this->itemAll.clear();

    while (!this->itemAvailable.empty()) {
      this->itemAvailable.pop();
    }
  }

  template <typename... Args>
  static std::shared_ptr<MemoryPool> Create(std::size_t capacity, Args &&...args) {
    auto *poolPtr = new MemoryPool(capacity);
    for (int32_t i = 0; i < poolPtr->capacity; i++) {
      auto *itemPtr = new ElementType(std::forward<Args>(args)...);
      poolPtr->itemAll.push_back(itemPtr);
      poolPtr->itemAvailable.push(itemPtr);
    }

    return std::shared_ptr<MemoryPool>(poolPtr);
  }

  bool GetSharedPtr(std::shared_ptr<ElementType> &sharedItemPtr, const int32_t timeout = 0) {
    unique_lock lck(mu);

    if (timeout > 0) {
      this->cv.wait_for(lck, std::chrono::milliseconds(timeout), [this] { return !this->itemAvailable.empty(); });
    } else {
      this->cv.wait(lck, [this] { return !this->itemAvailable.empty(); });
    }

    if (this->itemAvailable.empty()) {
      sharedItemPtr = nullptr;
      return false;
    }

    auto *itemPtr = this->itemAvailable.front();
    this->itemAvailable.pop();
    sharedItemPtr = std::shared_ptr<ElementType>(itemPtr, [this](ElementType *elementPtr) {
      elementPtr->Reset();
      this->itemAvailable.push(elementPtr);
      this->cv.notify_all();
    });

    return true;
  }

 private:
  mutex                     mu;
  std::condition_variable   cv;
  std::list<ElementType *>  itemAll;
  std::queue<ElementType *> itemAvailable;
  std::size_t               capacity;
};
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值