1. 为什么需要线程池规范
在C++多线程开发中,线程池是最基础也最容易出问题的组件之一。我见过太多项目因为线程池使用不当导致的内存泄漏、死锁甚至程序崩溃。最典型的一个案例是去年review一个金融交易系统时,发现他们直接在每个请求到来时创建新线程,高峰期线程数突破2000个,导致上下文切换开销吃掉近30%的CPU资源。
线程池规范的核心价值在于:
- 控制并发线程数量,避免资源耗尽
- 减少线程创建销毁的开销(实测显示创建线程的耗时是复用线程的100倍以上)
- 统一任务队列管理,防止任务丢失或堆积
- 提供一致的生命周期管理接口
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线程池实现的核心要素
2.1 线程数量动态调整
固定大小的线程池在实际场景中往往表现不佳。我的方案是根据系统CPU核心数和任务队列负载动态调整:
cpp复制// 根据硬件并发数初始化
unsigned init_size = std::thread::hardware_concurrency();
// 动态调整算法
if (task_queue.size() > init_size * 2) {
expand_worker(init_size / 2);
} else if (task_queue.size() < init_size / 4) {
shrink_worker(init_size / 4);
}
关键参数说明:
- 队列长度超过2倍线程数时扩容
- 队列空闲时收缩到初始值的1/4
- 设置最小保留线程数(通常4个)
2.2 任务队列的线程安全实现
双向阻塞队列是我的首选方案,结合了std::deque和条件变量:
cpp复制template<typename T>
class BlockingQueue {
std::deque<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
public:
void push(const T& item) {
{
std::unique_lock lock(mutex_);
queue_.push_back(item);
