-
Notifications
You must be signed in to change notification settings - Fork 1
Utils_ObjectsPool
SweerItTer edited this page Feb 1, 2026
·
3 revisions
ObjectsPool 是 utilsCore Utils 模块的核心类,提供对象池功能,用于管理可复用的对象实例,减少对象创建和销毁的开销。
- 预创建对象池
- 提供对象获取(acquire)和归还(release)
- 支持阻塞和超时获取
- 线程安全的对象池管理
- 频繁创建和销毁对象
- 对象初始化开销较大的场景
- 资源有限的环境
- YOLO 模型推理(rknnPool 使用)
- 对象复用: 避免重复创建对象
- 减少分配: 降低内存分配次数
- 线程安全: 内置互斥锁保护
- 依赖: C++ STL
- 被依赖: rknnPool, YOLO 处理器等模块
ObjectsPool 是对象池的模板类,管理类型为 T 的对象集合:
- 构造时预创建对象
- acquire() 获取空闲对象,无则阻塞等待
- release() 归还对象到池
- 支持超时获取
- 对象池模式: 复用对象,减少创建/销毁开销
- 生产者-消费者: 使用条件变量同步
- 模板模式: 支持任意可复制的对象类型
ObjectPool(size_t poolSize, CreatorFunc creator)参数说明:
-
poolSize(输入): 池的大小(对象数量) -
creator(输入): 对象创建函数std::function<T()>
返回值: 无
所有权归属:
- ObjectPool 拥有池中所有对象的所有权
注意事项:
- 构造时立即创建 poolSize 个对象
- creator 函数必须返回有效的对象
- 对象类型 T 必须支持移动语义
使用例程:
// 创建对象池,预创建 10 个对象
ObjectPool<MyClass> pool(10, []() {
return MyClass(); // 对象创建函数
});
// 使用 Lambda 创建带参数的对象
ObjectPool<MyClass> pool(10, []() {
return MyClass(42, "test");
});
// 使用工厂函数
MyClass createMyClass() {
return MyClass(100);
}
ObjectPool<MyClass> pool(5, createMyClass);T acquire()参数说明: 无
返回值:
- 成功: 返回对象(移动语义)
- 失败: 阻塞直到有对象可用
所有权归属:
- 返回对象的所有权转移给调用者
- 调用者负责归还对象到池
注意事项:
- 如果池为空,阻塞等待直到有对象可用
- 返回的对象使用移动语义
- 必须在使用后调用 release() 归还对象
使用例程:
ObjectPool<MyClass> pool(10, []() { return MyClass(); });
// 获取对象(阻塞等待)
MyClass obj = pool.acquire();
// 使用对象
obj.doSomething();
// 归还对象
pool.release(std::move(obj));bool tryAcquire(T& obj, std::chrono::milliseconds timeout)参数说明:
-
obj(输出): 输出参数,接收获取的对象 -
timeout(输入): 超时时间(毫秒)
返回值:
- 成功: 返回
true,obj 包含对象 - 失败/超时: 返回
false,obj 保持不变
所有权归属:
- 成功时对象的所有权转移给调用者
注意事项:
- 非阻塞获取,支持超时
- 超时返回 false,避免死锁
- obj 使用引用传递,通过移动语义赋值
使用例程:
ObjectPool<MyClass> pool(10, []() { return MyClass(); });
MyClass obj;
if (pool.tryAcquire(obj, std::chrono::milliseconds(1000))) {
// 成功获取对象
obj.doSomething();
pool.release(std::move(obj));
} else {
// 超时,没有可用对象
printf("Timeout: No available object\n");
}void release(T obj)参数说明:
-
obj(输入): 要归还的对象(移动语义)
返回值: 无
所有权归属:
- 对象的所有权转移回对象池
注意事项:
- 使用移动语义归还对象
- 归还后会唤醒一个等待的 acquire() 调用
- 如果池已满(理论上不会,因为池大小固定),对象会丢失
使用例程:
MyClass obj = pool.acquire();
// 使用对象...
pool.release(std::move(obj)); // 归还对象size_t freeCount() const参数说明: 无
返回值: 池中当前空闲对象数量
所有权归属:
- 只读访问,不转移所有权
注意事项:
- 返回值可能因多线程并发访问而快速变化
- 只能作为参考,不应依赖其做关键判断
使用例程:
printf("Free objects: %zu\n", pool.freeCount());template<typename T>
class ObjectPool {
private:
CreatorFunc creator_; // 对象创建函数
mutable std::mutex mutex_; // 互斥锁
std::condition_variable cond_; // 条件变量
std::queue<T> free_; // 空闲对象队列
};获取对象流程:
1. 调用 acquire()
↓
2. 获取互斥锁
↓
3. 等待条件变量(队列非空)
↓
4. 从队列前端取出对象
↓
5. 释放互斥锁
↓
6. 返回对象
归还对象流程:
1. 调用 release(obj)
↓
2. 获取互斥锁
↓
3. 对象推入队列尾部
↓
4. 通知一个等待线程
↓
5. 释放互斥锁
↓
6. 返回
| 资源 | 创建者 | 拥有者 | 释放方式 | 线程保护 |
|---|---|---|---|---|
| 池中对象 | creator 函数 | ObjectPool | ObjectPool 析构时 | mutex_ |
| acquire() 后的对象 | ObjectPool | 调用者 | 必须调用 release() | - |
| release() 后的对象 | 调用者 | ObjectPool | 重新入队 | mutex_ |
分配流:
creator() → ObjectPool 构造 → std::queue<T> → acquire() → 调用者持有
归还流:
调用者 → release(T&&) → std::queue<T> → 等待中的 acquire() → 新调用者持有
-
互斥锁:
std::mutex mutex_保护队列操作 -
条件变量:
std::condition_variable cond_实现等待/通知 - 原子操作: 无
-
acquire()可以多线程并发调用 -
tryAcquire()可以多线程并发调用 -
release()可以多线程并发调用 -
freeCount()可以多线程并发调用
- 对象类型 T 本身不是线程安全的,需要外部同步
- 多个线程获取同一个对象时,需要额外的同步机制
// 定义对象类型
class Worker {
public:
Worker(int id) : id_(id) {
printf("Worker %d created\n", id_);
}
~Worker() {
printf("Worker %d destroyed\n", id_);
}
void work() {
printf("Worker %d working\n", id_);
}
private:
int id_;
};
// 创建对象池
ObjectPool<Worker> pool(5, []() {
static int id = 0;
return Worker(++id);
});
// 获取和使用对象
Worker w = pool.acquire();
w.work();
pool.release(std::move(w));// YOLO 模型类型
class YoloModel {
public:
YoloModel(const std::string& path) {
// 加载模型
model_ = load_model(path);
}
~YoloModel() {
// 释放模型
release_model(model_);
}
object_detect_result_list infer(DmaBufferPtr buffer) {
// 执行推理
return run_inference(model_, buffer);
}
private:
ModelHandle model_;
};
// 创建模型池
ObjectPool<YoloModel> modelPool(5, [path]() {
return YoloModel(path);
});
// 使用模型推理
YoloModel model = modelPool.acquire();
auto result = model.infer(buffer);
modelPool.release(std::move(model));ObjectPool<Worker> pool(10, []() { return Worker(); });
std::vector<std::thread> threads;
for (int i = 0; i < 8; ++i) {
threads.emplace_back([&pool]() {
for (int j = 0; j < 100; ++j) {
Worker w = pool.acquire();
w.work();
pool.release(std::move(w));
}
});
}
for (auto& t : threads) {
t.join();
}ObjectPool<Worker> pool(5, []() { return Worker(); });
Worker w;
if (pool.tryAcquire(w, std::chrono::milliseconds(100))) {
// 成功获取
w.work();
pool.release(std::move(w));
} else {
// 超时
printf("Failed to acquire worker (timeout)\n");
}class DatabaseConnection {
public:
DatabaseConnection(const std::string& host, int port)
: host_(host), port_(port) {
// 建立连接
connect(host, port);
}
~DatabaseConnection() {
// 关闭连接
disconnect();
}
void query(const std::string& sql) { /* ... */ }
private:
std::string host_;
int port_;
};
// 使用 Lambda 创建连接
ObjectPool<DatabaseConnection> connPool(
5,
[]() {
return DatabaseConnection("localhost", 3306);
}
);
// 使用连接
DatabaseConnection conn = connPool.acquire();
conn.query("SELECT * FROM users");
connPool.release(std::move(conn));| 特性 | ObjectsPool | FixedSizePool |
|---|---|---|
| 类型 | 对象池 | 内存池 |
| 管理内容 | 对象实例 | 原始内存块 |
| 模板参数 | template<typename T> |
非模板 |
| 创建方式 | 通过 creator 函数 | 直接分配内存 |
| 返回类型 |
T(对象) |
void*(内存指针) |
| 初始化 | 对象构造函数完成 | 使用 placement new |
| 适用场景 | 复杂对象(如 YOLO 模型) | 简单数据结构(如缓冲区) |
- 对象类型: 对象类型 T 必须支持移动语义
- 对象状态: 归还的对象可能包含之前的状态,使用前需要重置
- 池大小: 构造时确定池大小,运行时不能调整
- 阻塞等待: acquire() 会阻塞,确保池中有对象
- 超时处理: 使用 tryAcquire() 避免死锁
- 对象生命周期: 归还的对象会被复用,不要保留对象引用
- 线程安全: 多线程获取不同对象是安全的,同一对象需要外部同步
- 资源清理: 析构时释放所有对象,确保对象正确清理资源
- FixedSizePool - 固定大小内存池
- AsyncThreadPool - 异步线程池
- Utils 模块总览
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器