babylon

[English]

object_pool

原理

典型的对象池实现,一般用于支持这样的应用场景

  1. 并行进行的一组计算需要用到某种资源
  2. 这种资源的实例在使用时需要被独占
  3. 创建和维护这种资源本身比较『昂贵』

典型如通信用的socket,用于模型推理的存储结构等

底层实现基于bounded_queue来提供wait-free的资源申请和归还,根据典型场景包装形成两种模式

  1. 严格有限模式:预先注入N个资源实例,当超出N个申请者后,后续申请者必须等待其他人归还后才能获取到
  2. 自动创建模式:在对象池资源不足时,申请者会获得临时创建的新资源实例,而当对象池中空闲量超过N时,后续归还的资源实例会被释放

使用方法

#include "babylon/concurrent/object_pool.h"

// 默认构造的对象池容量为0,需要经过设置后才可使用
::babylon::ObjectPool<R> pool;

// 设置最大容量
pool.reserve_and_clear(N);

// 设置自动清理函数,设置后对于进入对象池的实例,会自动调用清理函数
// 注意:对自动创建模式,溢出后直接销毁的实例也会在销毁前先进行清理
pool.set_recycler([] (R& resource) {
    // 清理资源实例
});

/////////////////
// 严格有限模式
for (...) {
    // 预先注入定量的实例
    pool.push(std::make_unique<R>(...));
}
parallel loop:
    // 通过pop获取实例,如果对象池为空,会阻塞等待直到有实例被归还
    auto ptr = pool.pop();
    ptr->...; // 返回值为定制Deleter的智能指针
    // 析构时实例自动归还
/////////////////

/////////////////
// 自动创建模式
// 通过设置构造回调来启用自动创建模式
pool.set_creator([] {
    return new R(...);
});
parallel loop:
    // 通过pop获取实例,如果对象池为空,会自动调用构造回调
    auto ptr = pool.pop();
    ptr->...; // 返回值为定制Deleter的智能指针
    // 析构时实例自动归还,池内实例超出容量N后,超出部分会直接销毁
/////////////////