An open API service indexing awesome lists of open source software.

https://github.com/hsll175848494/threadpool

高性能C++11线程池,具备线程独享任务队列、CPU核心绑定、栈上分配任务、任务窃取及优先任务支持
https://github.com/hsll175848494/threadpool

blockqueue cpp11 threadpool

Last synced: 9 months ago
JSON representation

高性能C++11线程池,具备线程独享任务队列、CPU核心绑定、栈上分配任务、任务窃取及优先任务支持

Awesome Lists containing this project

README

          

# HSLL::ThreadPool

## 概述
HSLL::ThreadPool 一个轻量级C++11线程池实现,具有以下核心特性:

1. **多队列架构** - 每个工作线程拥有独立的任务队列(固定容量),减少锁争用
2. **核心绑定** - 支持将工作线程绑定到指定CPU核心(Linux/Windows), 避免缓存失效
3. **负载均衡** - 采用round-robin+二级队列选取机制+任务窃取机制实现负载均衡
4. **定长任务容器** - 基于栈的预分配任务容器,将所有参数储存在栈上,避免动态申请空间
5. **多提交接口** - 提供阻塞/非阻塞、单任务/批量任务等多种接口
6. **双端插入支持** - 支持从队列头/尾插入以适应不同任务优先级
7. **优雅关闭** - 支持立即关闭和等待任务完成的优雅关闭模式

## 引入
```cpp
//依赖于TPBlockQueue.hpp和TPTask.hpp,请确保处于ThreadPool.hpp同级目录
#include "ThreadPool.hpp"
```

## 核心组件

### ThreadPool 类模板

#### 模板参数
```cpp
template >
class ThreadPool
```
- `T`: 任务类型,需实现 `execute()` 方法,默认使用基于栈的预分配任务容器

#### 初始化方法
```cpp
bool init(unsigned queueLength, unsigned threadNum, unsigned batchSize = 1)
```
- **参数**:
- `queueLength`: 每个工作队列的容量
- `threadNum`: 工作线程数量
- `batchSize`: 单次处理任务数(单次从任务队列中取出多少任务)
- **返回值**:初始化成功返回true
- **功能**:分配资源并启动工作线程

#### 任务提交接口

```cpp

enum INSERT_POS
{
TAIL, //插入到队列尾部
HEAD //插入到队列头部
};
```

1. **单任务提交(就地构造)**
```cpp
template
bool emplace(Args &&...args)

template
bool wait_emplace(Args &&...args)

template
bool wait_emplace(const std::chrono::duration &timeout, Args &&...args)
```

2. **单任务提交**
```cpp
template
bool enqueue(U &&task)

template
bool wait_enqueue(U &&task)

template
bool wait_enqueue(U &&task, const std::chrono::duration &timeout)
```

3. **批量提交**
```cpp
template
unsigned int enqueue_bulk(T *tasks, unsigned int count)

template
unsigned int wait_enqueue_bulk(T *tasks, unsigned int count)

template
unsigned int wait_enqueue_bulk(T *tasks, unsigned int count, const std::chrono::duration &timeout)
```
```cpp
enum BULK_CMETHOD
{
COPY, // 使用拷贝语义,将任务拷贝到队列。原任务数组依旧有效
MOVE // 使用移动语义,将任务移动到队列
};
```
#### 关闭方法
```cpp
void exit(bool shutdownPolicy = true)
```
- `shutdownPolicy`:
- true: 优雅关闭(执行完队列剩余任务)
- false: 立即关闭

#### 工作机制
- **任务分发**:采用轮询+跳半队列负载均衡策略
- **工作线程**:每个线程优先处理自己的队列,空闲时支持任务窃取
- **核心绑定**:自动将工作线程绑定到不同CPU核心(需硬件支持)

### 基本使用
```cpp
HSLL::ThreadPool<> pool;
pool.init(1000, 4); // 4线程,每队列容量1000

// 提交lambda任务
pool.emplace([]{
std::cout << "Task executed!\n";
});

// 提交带参数的函数
void taskFunc(int a, double b) { /*...*/ }

//添加任务示例
pool.enqueue(taskFunc, 42, 3.14);

//异步示例
std::promise resultPromise;
auto resultFuture = resultPromise.get_future();
pool.emplace([&resultPromise] {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
resultPromise.set_value(sum);
});
int total = resultFuture.get();

//线程池析构时自动调用exit(false), 但仍然建议手动调用以控制退出行为
pool.exit(true); // 优雅关闭
```

### 任务生命周期
```mermaid
graph TD
A[任务提交] --> B{提交方式}
B -->|emplace/wait_emplace| C[在队列存储中
直接构造任务]
B -->|enqueue/wait_enqueue| D[用户构造任务对象
拷贝/移动到队列存储]

C --> E[工作线程从队列取出任务]
D --> E

E --> F[在预分配执行内存上
就地构造(移动构造)]
F --> G[执行execute方法]
G --> H[显式调用析构函数]
H --> I[清理执行内存]
```

### 性能优化建议
1. **批量提交**:优先使用`enqueue_bulk`处理任务组
2. **任务大小**:根据任务复杂度选择合适存储模板参数
3. **线程数量**:通常设置为CPU核心数
4. **队列容量**:根据任务吞吐量需求调整

## 注意事项
1. **类型匹配**:提交任务类型必须严格匹配队列任务类型
2. **对齐要求**:任务最大对齐值必须小于等于队列任务类型的对齐值
3. **异常安全**:
- 任务允许在默认构造时抛出异常,但拷贝/移动构造不允许抛出异常
- execute()方法不允许抛出异常,需要在任务内部捕获并处理所有可能的异常
4. **参数传递**:
- 大型对象应使用指针或移动语义传递
- 避免在任务中捕获可能失效的引用
5. **结果获取**:
- 使用std::promise/std::future获取异步结果
- promise必须在任务执行期间保持有效

## 接口对比表

| 方法类型 | 非阻塞 | 阻塞等待 | 超时等待 |
|-------------|------------|------------|--------------|
| 单任务提交 | emplace | wait_emplace| wait_emplace |
| 预构建任务 | enqueue | wait_enqueue| wait_enqueue |
| 批量任务 | enqueue_bulk| wait_enqueue_bulk | wait_enqueue_bulk |

## 平台支持
- Linux (pthread affinity)
- Windows (SetThreadAffinityMask)
- C++11 或更新标准

## 其它
- **组件文档**: `document`
- **性能测试**: `performance test`