-
Notifications
You must be signed in to change notification settings - Fork 1
Utils_FixedSizePool
SweerItTer edited this page Feb 1, 2026
·
3 revisions
FixedSizePool 是 utilsCore 核心模块的高性能内存池类,提供固定大小的内存块管理,用于减少内存分配开销,通过线程本地缓存(TLS)和批量操作实现高并发性能。
- 管理固定大小的内存块池
- 提供超高速的内存块分配和释放
- 通过线程本地缓存减少锁竞争
- 支持批量填充和刷新操作
- 高频内存分配和释放
- 多线程高并发环境
- 固定大小对象的内存管理
- RGA、V4L2 等硬件模块的缓冲区管理
- Frame 对象的底层内存池
- 线程本地缓存: 每个线程独占缓存,避免锁竞争
- 批量操作: 减少锁持有时间
- 缓存行对齐: 防止伪共享(alignas(64))
- 分支预测优化: 使用 LIKELY/UNLIKELY 宏
- 依赖: C++ STL, thread_local
- 被依赖: RgaProcessor, Frame, CameraController 等上层模块
FixedSizePool 是固定大小内存池的实现,提供:
- 固定大小内存块的快速分配(
allocate()) - 内存块的快速释放(
deallocate()) - 自动内存管理和批量操作
- 线程本地缓存优化
- 对象池模式: 复用内存块,减少分配开销
- TLS 模式: 线程本地缓存,减少锁竞争
- 批量操作: refill/flush 批量填充和刷新
Node 是内存块链表节点,用于构建空闲链表。
struct Node {
Node* next;
};| 字段 | 类型 | 说明 |
|---|---|---|
next |
Node* |
指向下一个空闲节点的指针 |
ThreadCache 是线程本地缓存,使用 alignas(64) 防止伪共享。每个线程独享一个缓存,减少锁竞争。
struct alignas(ARCH_LINE_SIZE) ThreadCache {
void* blocks[TLS_CACHE_SIZE];
size_t count = 0;
FixedSizePool* owner = nullptr;
~ThreadCache() {
if (owner && count > 0) owner->flush_all(this);
}
};| 字段 | 类型 | 说明 |
|---|---|---|
blocks |
void*[TLS_CACHE_SIZE] |
缓存的内存块数组 |
count |
size_t |
当前缓存的内存块数量 |
owner |
FixedSizePool* |
所属的内存池指针 |
| 参数 | ARM 架构 | x86 架构 | 说明 |
|---|---|---|---|
ARCH_LINE_SIZE |
64 | 64 | 缓存行大小 |
TLS_CACHE_SIZE |
1024 | 2048 | 线程缓存最大容量 |
TLS_BATCH_SIZE |
256 | 512 | 批量填充/刷新大小 |
FixedSizePool(size_t blockSize, size_t blocksPerPage = 2048, size_t alignment = 64, size_t prealloc = 0)参数说明:
-
blockSize(输入): 单个内存块大小(字节) -
blocksPerPage(输入): 每页分配的内存块数量,默认 2048 -
alignment(输入): 内存对齐要求,默认 64 字节 -
prealloc(输入): 预分配的页数,默认 0
返回值: 无
所有权归属:
- FixedSizePool 拥有所有内存块的所有权
注意事项:
-
blockSize会被自动对齐到alignment的倍数 - 最小
blockSize为sizeof(Node*)(8 字节) -
prealloc> 0 时会立即分配内存页 - 对齐参数影响缓存性能,建议使用 64 字节
使用例程:
// 创建 128 字节内存块池,每页 2048 个块
FixedSizePool pool(128);
// 创建 256 字节内存块池,预分配 2 页
FixedSizePool pool(256, 2048, 64, 2);
// 创建 512 字节内存块池,自定义对齐
FixedSizePool pool(512, 1024, 128);~FixedSizePool()参数说明: 无
返回值: 无
所有权归属:
- 释放所有内存页
注意事项:
- 析构时会自动回收所有线程缓存的内存块
- 使用
_aligned_free(Windows)或free(Linux)释放内存 - 析构后所有分配的内存块都变为无效
void* allocate()参数说明: 无
返回值:
- 成功: 返回内存块指针
- 失败: 返回
nullptr(内存不足)
所有权归属:
- 返回的内存块由调用者持有
- 必须使用
deallocate()归还
注意事项:
- 首先从线程本地缓存获取
- 缓存为空时调用
refill()批量填充 - 极其精简,适合 inline 展开
- 时间复杂度: O(1)(缓存命中)
使用例程:
FixedSizePool pool(128);
// 分配内存块
void* ptr = pool.allocate();
if (ptr) {
// 使用内存块
memset(ptr, 0, 128);
// 使用后归还
pool.deallocate(ptr);
} else {
printf("Memory allocation failed\n");
}void deallocate(void* p)参数说明:
-
p(输入): 要释放的内存块指针
返回值: 无
所有权归属:
- 内存块所有权归还给 FixedSizePool
注意事项:
-
p为nullptr时直接返回 - 释放到线程本地缓存
- 缓存满时调用
flush()批量刷新到全局 - 时间复杂度: O(1)
使用例程:
FixedSizePool pool(128);
void* ptr = pool.allocate();
// 使用内存块
MyStruct* obj = (MyStruct*)ptr;
obj->value = 42;
// 释放内存块
pool.deallocate(ptr);ThreadCache* get_fast_thread_cache()职责与用途:
使用 thread_local 获取当前线程的缓存,确保每个线程独享缓存。
实现要点:
- 使用
static thread_local ThreadCache cache - 首次使用时设置
owner - 无锁访问,极快
void refill(ThreadCache* cache)职责与用途: 从全局空闲链表批量获取内存块,填充到线程缓存。
参数说明:
-
cache(输入): 线程本地缓存指针
填充策略:
- 尽量填满缓存或拿走一个 Batch(
TLS_BATCH_SIZE) - 使用
central_mutex_保护全局链表
void flush(ThreadCache* cache)职责与用途: 将线程本地缓存的一半内存块刷新到全局空闲链表。
参数说明:
-
cache(输入): 线程本地缓存指针
刷新策略:
- 回冲一半缓存到全局
- 保留一半在本地继续使用
- 在锁外构造链表,减少锁持有时间
void flush_all(ThreadCache* cache)职责与用途: 将线程本地缓存的所有内存块刷新到全局空闲链表。
参数说明:
-
cache(输入): 线程本地缓存指针
调用时机:
- 线程退出时(
ThreadCache析构函数)
void expand(size_t pages)职责与用途: 分配指定数量的内存页,扩展内存池。
参数说明:
-
pages(输入): 要分配的页数
使用场景:
- 预分配内存(构造函数调用)
- 动态扩展内存池
void expand_internal()职责与用途: 分配单个内存页,初始化并链接到空闲链表。
实现要点:
- 使用
_aligned_malloc(Windows)或posix_memalign(Linux) - 初始化为单向链表
- 挂载到全局空闲链表头部
┌─────────────────────────────────────────────────────────┐
│ FixedSizePool │
├─────────────────────────────────────────────────────────┤
│ ThreadCache (thread_local, 每线程一个) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ blocks[2048] ← void* 指针数组 │ │
│ │ count = 1024 ← 当前缓存数量 │ │
│ │ owner = this ← 所属池指针 │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ Global Freelist (中心空闲链表) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ freelist_head_ → Node → Node → ... │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ Memory Pages(内存页) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Page 1: [Block][Block]...[Block] │ │
│ │ Page 2: [Block][Block]...[Block] │ │
│ │ ... │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
1. 调用 allocate()
↓
2. 获取线程本地缓存 (get_fast_thread_cache)
↓
3. 检查缓存是否为空 (cache->count == 0)
↓
4. 如果为空,调用 refill() 批量填充
↓
5. 从缓存末尾取出一个内存块
↓
6. 返回内存块指针
1. 调用 deallocate(void* p)
↓
2. 检查指针是否为 nullptr
↓
3. 获取线程本地缓存
↓
4. 检查缓存是否已满 (cache->count >= TLS_CACHE_SIZE)
↓
5. 如果已满,调用 flush() 批量刷新
↓
6. 将内存块放入缓存
↓
7. 缓存计数加 1
| 资源 | 拥有者 | 释放方式 | 线程保护 |
|---|---|---|---|
| 内存页 | FixedSizePool | ~FixedSizePool() |
page_mutex_ |
| 全局空闲链表 | FixedSizePool | ~FixedSizePool() |
central_mutex_ |
| allocate() 后的内存块 | 调用者 | 必须调用 deallocate()
|
- |
| deallocate() 后的内存块 | FixedSizePool | 重新入池 | - |
分配流:
FixedSizePool → allocate() → void* → 调用者持有
归还流:
调用者 → deallocate(void*) → ThreadCache → 全局空闲链表
-
ThreadCache:
thread_local,每个线程独享,无锁访问 -
全局空闲链表:
central_mutex_保护 -
内存页管理:
page_mutex_保护 -
内存池扩展:
expand_mutex_保护
| 锁名称 | 保护资源 | 使用场景 |
|---|---|---|
central_mutex_ |
全局空闲链表 | refill, flush |
page_mutex_ |
内存页列表 | expand_internal, 析构 |
expand_mutex_ |
扩展操作 | expand |
-
allocate()和deallocate()可以多线程并发调用 - 线程本地缓存自动管理,无需外部同步
- 线程退出时自动刷新缓存到全局
- 避免跨线程传递内存块
static thread_local ThreadCache cache;- 每个线程独享缓存
- 无锁访问,减少竞争
- 线程退出时自动清理
// 批量填充
refill(ThreadCache* cache) {
size_t take = std::min(TLS_BATCH_SIZE, TLS_CACHE_SIZE - cache->count);
// 批量取出内存块
}
// 批量刷新
flush(ThreadCache* cache) {
size_t to_flush = TLS_BATCH_SIZE;
// 批量归还内存块
}- 减少锁获取次数
- 提高缓存命中率
struct alignas(ARCH_LINE_SIZE) ThreadCache {
// ...
};- 防止伪共享
- 提高 CPU 缓存效率
if (UNLIKELY(cache->count == 0)) {
refill(cache);
}- 告诉编译器分支概率
- 优化 CPU 指令流水线
// 创建 128 字节内存块池
FixedSizePool pool(128);
// 分配和使用内存块
for (int i = 0; i < 1000; ++i) {
void* ptr = pool.allocate();
if (ptr) {
// 使用内存块
MyStruct* obj = (MyStruct*)ptr;
obj->id = i;
obj->value = i * 2;
// 处理完成后释放
pool.deallocate(ptr);
}
}class RgaProcessor {
private:
FixedSizePool buffer_pool_;
size_t buffer_size_;
public:
RgaProcessor(int width, int height, uint32_t format)
: buffer_size_(calculateBufferSize(width, height, format))
, buffer_pool_(buffer_size_, 1024, 64, 2) {
// 预分配 2 页缓冲区
}
void* allocateBuffer() {
return buffer_pool_.allocate();
}
void releaseBuffer(void* buffer) {
if (buffer) {
buffer_pool_.deallocate(buffer);
}
}
private:
size_t calculateBufferSize(int width, int height, uint32_t format) {
// 根据格式计算缓冲区大小
return width * height * 2; // 假设 NV12 格式
}
};#include <thread>
#include <vector>
FixedSizePool pool(256, 2048, 64, 10);
void worker(int id) {
for (int i = 0; i < 10000; ++i) {
void* ptr = pool.allocate();
if (ptr) {
// 模拟处理
memset(ptr, id, 256);
pool.deallocate(ptr);
}
}
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 8; ++i) {
threads.emplace_back(worker, i);
}
for (auto& t : threads) {
t.join();
}
return 0;
}class FramePool {
private:
FixedSizePool frame_pool_;
size_t frame_size_;
public:
FramePool(int width, int height, uint32_t format)
: frame_size_(width * height * 4) // RGBA 格式
, frame_pool_(frame_size_, 1024, 64, 5) {
}
std::shared_ptr<void> allocateFrame() {
void* ptr = frame_pool_.allocate();
if (ptr) {
return std::shared_ptr<void>(ptr, [this](void* p) {
frame_pool_.deallocate(p);
});
}
return nullptr;
}
};template<typename T>
class ObjectPool {
private:
FixedSizePool pool_;
public:
ObjectPool(size_t count = 1024)
: pool_(sizeof(T), count, 64, 1) {
}
T* allocate() {
void* ptr = pool_.allocate();
if (ptr) {
return new(ptr) T(); // placement new
}
return nullptr;
}
void deallocate(T* obj) {
if (obj) {
obj->~T(); // 调用析构函数
pool_.deallocate(obj);
}
}
};
// 使用
ObjectPool<MyClass> pool;
MyClass* obj = pool.allocate();
if (obj) {
obj->doSomething();
pool.deallocate(obj);
}通过重载类的 new/delete 操作符,让对象自动使用内存池分配:
class MyClass {
public:
int id;
double value;
MyClass() : id(0), value(0.0) {}
MyClass(int i, double v) : id(i), value(v) {}
void doSomething() {
printf("MyClass: id=%d, value=%f\n", id, value);
}
// 重载 new 操作符
void* operator new(size_t size) {
return my_pool.allocate();
}
// 重载 delete 操作符
void operator delete(void* ptr) {
my_pool.deallocate(ptr);
}
// 支持 new[] 和 delete[]
void* operator new[](size_t size) {
return my_pool.allocate();
}
void operator delete[](void* ptr) {
my_pool.deallocate(ptr);
}
private:
static FixedSizePool my_pool;
};
// 静态成员初始化
FixedSizePool MyClass::my_pool(sizeof(MyClass), 1024, 64, 2);
// 使用方式 - 与普通 new/delete 完全一致
int main() {
// 自动使用内存池分配
MyClass* obj1 = new MyClass(1, 3.14);
obj1->doSomething();
delete obj1; // 自动归还到内存池
// 数组分配
MyClass* obj2 = new MyClass[5];
for (int i = 0; i < 5; ++i) {
obj2[i].id = i;
obj2[i].value = i * 1.5;
}
delete[] obj2;
return 0;
}创建兼容 STL 容器的自定义分配器:
template<typename T>
class PoolAllocator {
public:
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = size_t;
using difference_type = ptrdiff_t;
PoolAllocator() noexcept : pool_(sizeof(T), 1024, 64, 1) {}
template<typename U>
PoolAllocator(const PoolAllocator<U>&) noexcept {}
template<typename U>
struct rebind {
using other = PoolAllocator<U>;
};
T* allocate(size_type n) {
if (n != 1) {
throw std::bad_alloc();
}
void* ptr = pool_.allocate();
if (!ptr) {
throw std::bad_alloc();
}
return static_cast<T*>(ptr);
}
void deallocate(T* p, size_type) noexcept {
if (p) {
pool_.deallocate(p);
}
}
template<typename U, typename... Args>
void construct(U* p, Args&&... args) {
::new((void*)p) U(std::forward<Args>(args)...);
}
template<typename U>
void destroy(U* p) noexcept {
p->~U();
}
private:
FixedSizePool pool_;
};
// 使用自定义分配器的 STL 容器
int main() {
// 使用内存池的 vector
std::vector<MyClass, PoolAllocator<MyClass>> vec;
for (int i = 0; i < 1000; ++i) {
vec.emplace_back(i, i * 2.5);
}
// 使用内存池的 list
std::list<int, PoolAllocator<int>> lst;
for (int i = 0; i < 1000; ++i) {
lst.push_back(i);
}
// 使用内存池的 map
std::map<int, double, std::less<int>,
PoolAllocator<std::pair<const int, double>>> mp;
for (int i = 0; i < 1000; ++i) {
mp[i] = i * 1.5;
}
return 0;
}使用智能指针自动管理内存池对象的生命周期:
template<typename T>
class PooledObjectDeleter {
public:
PooledObjectDeleter(FixedSizePool& pool) : pool_(pool) {}
void operator()(T* ptr) const {
if (ptr) {
ptr->~T(); // 调用析构函数
pool_.deallocate(ptr);
}
}
private:
FixedSizePool& pool_;
};
template<typename T>
class PooledObject {
private:
FixedSizePool pool_;
public:
PooledObject(size_t count = 1024)
: pool_(sizeof(T), count, 64, 1) {}
using unique_ptr = std::unique_ptr<T, PooledObjectDeleter<T>>;
unique_ptr create() {
void* ptr = pool_.allocate();
if (ptr) {
return unique_ptr(new(ptr) T(), PooledObjectDeleter<T>(pool_));
}
return nullptr;
}
template<typename... Args>
unique_ptr create(Args&&... args) {
void* ptr = pool_.allocate();
if (ptr) {
return unique_ptr(
new(ptr) T(std::forward<Args>(args)...),
PooledObjectDeleter<T>(pool_)
);
}
return nullptr;
}
};
// 使用方式
int main() {
PooledObject<MyClass> pool;
// 创建对象
auto obj1 = pool.create();
if (obj1) {
obj1->doSomething();
} // 自动释放
// 带参数创建
auto obj2 = pool.create(42, 3.14159);
if (obj2) {
obj2->doSomething();
} // 自动释放
return 0;
}根据对象大小选择不同的内存池:
class HybridAllocator {
public:
HybridAllocator() {
// 小对象池 (<= 64 字节)
small_pool_ = std::make_unique<FixedSizePool>(64, 2048, 64, 2);
// 中等对象池 (<= 256 字节)
medium_pool_ = std::make_unique<FixedSizePool>(256, 1024, 64, 2);
// 大对象池 (<= 1024 字节)
large_pool_ = std::make_unique<FixedSizePool>(1024, 512, 64, 1);
}
void* allocate(size_t size) {
if (size <= 64) {
return small_pool_->allocate();
} else if (size <= 256) {
return medium_pool_->allocate();
} else if (size <= 1024) {
return large_pool_->allocate();
} else {
// 超大对象直接使用 malloc
return malloc(size);
}
}
void deallocate(void* ptr, size_t size) {
if (size <= 64) {
small_pool_->deallocate(ptr);
} else if (size <= 256) {
medium_pool_->deallocate(ptr);
} else if (size <= 1024) {
large_pool_->deallocate(ptr);
} else {
free(ptr);
}
}
private:
std::unique_ptr<FixedSizePool> small_pool_;
std::unique_ptr<FixedSizePool> medium_pool_;
std::unique_ptr<FixedSizePool> large_pool_;
};
// 使用方式
int main() {
HybridAllocator allocator;
// 自动选择合适的内存池
void* small = allocator.allocate(32);
void* medium = allocator.allocate(128);
void* large = allocator.allocate(512);
void* huge = allocator.allocate(2048);
allocator.deallocate(small, 32);
allocator.deallocate(medium, 128);
allocator.deallocate(large, 512);
allocator.deallocate(huge, 2048);
return 0;
}为内存池添加性能统计功能:
class PoolWithStats {
public:
PoolWithStats(size_t blockSize, size_t blocksPerPage = 2048,
size_t alignment = 64, size_t prealloc = 0)
: pool_(blockSize, blocksPerPage, alignment, prealloc)
, alloc_count_(0)
, dealloc_count_(0)
, total_alloc_time_(0)
, total_dealloc_time_(0) {}
void* allocate() {
auto start = std::chrono::high_resolution_clock::now();
void* ptr = pool_.allocate();
auto end = std::chrono::high_resolution_clock::now();
if (ptr) {
alloc_count_++;
total_alloc_time_ +=
std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
}
return ptr;
}
void deallocate(void* p) {
if (!p) return;
auto start = std::chrono::high_resolution_clock::now();
pool_.deallocate(p);
auto end = std::chrono::high_resolution_clock::now();
dealloc_count_++;
total_dealloc_time_ +=
std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
}
void printStats() const {
printf("=== Memory Pool Statistics ===\n");
printf("Total allocations: %zu\n", alloc_count_);
printf("Total deallocations: %zu\n", dealloc_count_);
printf("Current allocations: %zu\n", alloc_count_ - dealloc_count_);
if (alloc_count_ > 0) {
printf("Avg alloc time: %.2f ns\n",
(double)total_alloc_time_ / alloc_count_);
}
if (dealloc_count_ > 0) {
printf("Avg dealloc time: %.2f ns\n",
(double)total_dealloc_time_ / dealloc_count_);
}
printf("==============================\n");
}
private:
FixedSizePool pool_;
std::atomic<size_t> alloc_count_;
std::atomic<size_t> dealloc_count_;
std::atomic<uint64_t> total_alloc_time_;
std::atomic<uint64_t> total_dealloc_time_;
};
// 使用方式
int main() {
PoolWithStats pool(128);
// 分配和释放大量对象
for (int i = 0; i < 1000000; ++i) {
void* ptr = pool.allocate();
if (ptr) {
pool.deallocate(ptr);
}
}
// 打印统计信息
pool.printStats();
return 0;
}-
内存块大小: 内存块大小会在构造时自动对齐到
alignment的倍数 -
最小大小: 内存块最小为
sizeof(Node*)(8 字节) - 线程本地缓存: 线程退出时自动刷新缓存,无需手动处理
- 跨线程传递: 避免在不同线程间传递和释放内存块
- 指针有效性: 析构后所有分配的指针都变为无效
-
空指针检查:
deallocate(nullptr)安全,会直接返回 -
内存泄漏: 必须确保所有分配的内存块都被
deallocate() - 性能监控: 建议监控分配失败率,适当调整预分配数量
- new/delete 重载: 重载操作符是类级别的,所有对象共享同一个内存池
- STL 分配器: 确保 rebind 正确实现,否则某些容器可能无法工作
| 操作 | malloc/free | FixedSizePool | 性能提升 |
|---|---|---|---|
| 单线程分配 | ~100 ns | ~5 ns | 20x |
| 单线程释放 | ~100 ns | ~5 ns | 20x |
| 多线程分配 | ~200 ns | ~10 ns | 20x |
| 多线程释放 | ~200 ns | ~10 ns | 20x |
| 内存碎片 | 有 | 无 | - |
| 缓存命中率 | 低 | 高 | - |
| 架构 | TLS_CACHE_SIZE | TLS_BATCH_SIZE | 推荐场景 |
|---|---|---|---|
| ARM | 1024 | 256 | 嵌入式设备 |
| x86 | 2048 | 512 | 桌面/服务器 |
- ObjectsPool - C++ 对象池
- AsyncThreadPool - 异步线程池
- RgaProcessor - RGA 处理器
- Frame - 帧数据接口
- DmaBuffer - DMA-BUF 缓冲区
- 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 监视器