高性能线程池

本文主要讨论线程池相关知识。

项目背景

在高并发业务场景下,频繁创建/销毁线程会导致系统资源开销过大、调度效率降低,因此需要轻量级、高可用线程池组件,统一管理线程生命周期、复用线程资源,提升任务调度效率和系统稳定性。
技术栈

C++11 及以上均兼容、多线程编程、并发控制、设计模式(生产/消费者模式)。
核心实现 线程管理:支持指定线程数量初始化,线程池启动时创建固定数量工作线程,停止时回收所有线程资源;

任务调度:提供通用任务提交接口,支持任意可调用对象(函数、lambda、成员函数),并异步获取任务执行结果;

队列控制:基于条件变量实现任务队列的"满 / 空"状态感知,避免任务堆积或线程空等,提升资源利用率;

异常处理:对非法参数(线程数/队列容量≤0)、线程池停止后提交任务等场景抛出明确异常,增强鲁棒性。
项目亮点 高性能:任务执行在锁外完成,减少互斥锁持有时间,降低线程阻塞概率;通过条件变量精准唤醒线程,避免忙等;

通用性:模板化任务提交接口,支持任意类型的可调用对象,适配不同业务场景的任务需求;

安全性:禁用拷贝/移动构造函数,避免线程池对象被非法拷贝导致的资源冲突;完善的异常处理机制,覆盖参数校验、线程池状态校验等场景;

易用性:简洁的接口设计(初始化、提交任务、停止),测试用例覆盖基础功能。

项目目录结构

文件简介

复制代码
ThreadPool.h:线程池相关定义
 
ThreadPool.cpp:线程池相关实现
 
test.cpp:线程池测试
 
run.sh:编译运行脚本
 
thread:可执行二进制程序
 
thread.log:程序运行日志

ThreadPool.h

复制代码
/*
 *  変更历史:
 *  2026-05-09 cxb 创建该文件
 */

/*
 * @file ThreadPool.h
 * @brief
 * 功能:线程池
 */

#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__

#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <vector>
#include <queue>
#include <future>
#include <stdexcept>
#include <memory>

class ThreadPool
{
public:
    /* 线程池构造: 初始化线程数和队列最大容量*/
    explicit ThreadPool(size_t ThreadNum, size_t QueueMaxSize);
    /* 线程析构:停止线程池 */
    ~ThreadPool();
    /* 提交任务(函数,lambda,成员函数) */
    template<typename F, typename... Args>
    auto SubmitTask(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>
    {
        /* 推导任务类型 */
        using RetType = typename std::result_of<F(Args...)>::type;
        /* 打包任务无无参对象 */
        auto task = std::make_shared<std::packaged_task<RetType()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        /* 同步任务运行结果给外部 */
        std::future<RetType> future = task->get_future();

        {
            std::unique_lock<std::mutex> lock(mtx);

            /* 等待提交任务,线程停止或任务队列有空,处理虚唤醒 */
            CVNotFull.wait(lock, [this](){
                return StopFlag || tasks.size() < QueueMaxSize;
            });

            /* 线程池停止抛出异常 */
            if(StopFlag)
            {
                throw std::runtime_error("ThreadPool is shutdowning");
            }

            /* 提交任务到队列尾 */
            tasks.emplace([task](){ (*task)(); });
        }

        /* 唤醒线程处理新任务 */
        CVNotEmpty.notify_one();
        return future;
    }

    /* 启动线程池 */
    void start();

    /* 停止线程池 */
    void stop();

    /* 获取待执行任务数量 */
    size_t WaitRunTaskCount() const;

private:
    /* 不支持拷贝,复制,移动构造 */
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool(ThreadPool&&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    ThreadPool& operator=(ThreadPool&&) = delete;

    size_t ThreadNum;                           /* 线程数 */ 
    size_t QueueMaxSize;                        /* 任务队列容量 */
    bool StopFlag;                              /* 线程池停止标记 */
    std::vector<std::thread> WorkThreads;       /* 线程组 */
    std::queue<std::function<void()>> tasks;    /* 任务组 */
    mutable std::mutex mtx;                     /* 线程锁 */
    std::condition_variable CVNotEmpty;         /* 任务队列非空条件 */
    std::condition_variable CVNotFull;          /* 任务队列未满条件 */
};

#endif

ThreadPool.cpp

复制代码
/*
 *  変更历史:
 *  2026-05-09 cxb 创建文件
 */

/*
 * @file ThreadPool.cpp
 * @brief 
 * 功能:实现线程池接口
 */

#include "ThreadPool.h"

/* 线程池构造:初始化线程数量和任务队列最大容量,启动线程池 */
ThreadPool::ThreadPool(size_t ThreadNum, size_t QueueMaxSize)
    : ThreadNum(ThreadNum)
    , QueueMaxSize(QueueMaxSize)
    , StopFlag(false)
{
        /* 检验线程数量和任务队列最大容量 */
    if(ThreadNum <= 0 || QueueMaxSize <= 0)
    {
        throw std::invalid_argument("ThreadPool param error!");
    }

    /* 启动线程池 */
    start();
}

/* 线程池析构 */
ThreadPool::~ThreadPool()
{
    /* 停止线程池 */
    stop();
}

/* 启动线程池 */
void ThreadPool::start()
{
    /* 创建指定线程数量 */
    for(size_t i = 0; i < ThreadNum; i++)
    {
        WorkThreads.emplace_back([this](){
            /* 持续消费任务*/
            while(true)
            {
                std::function<void()> task;
                {
                    std::unique_lock<std::mutex> lock(mtx);

                    /* 等待消费任务,停止线程池或任务队列不为空唤醒,处理虚唤醒*/
                    CVNotEmpty.wait(lock, [this](){
                        return StopFlag || !tasks.empty();
                    });

                    /* 校验线程未停止且任务队列不为空 */
                    if(StopFlag && tasks.empty())
                    {
                        return;
                    }

                    /* 从队列头中提取任务 */
                    task = std::move(tasks.front());
                    tasks.pop();
                }

                /* 唤醒生产者提交任务 */
                CVNotFull.notify_one();
                /* 锁外执行任务,减少任务执行阻塞队列,提高效率*/
                task();
            }
        });
    }
}

/* 停止线程池 */
void ThreadPool::stop()
{
    /* 防止重复停止 */
    {
        std::unique_lock<std::mutex> lock(mtx);
        if(StopFlag)
            return;
        StopFlag = true;
    }

    /* 唤醒所有线程 */
    CVNotFull.notify_all();
    CVNotEmpty.notify_all();

    /* 逐个等待线程结束,回收资源 */
    for(std::thread& t : WorkThreads)
    {
        if(t.joinable())
            t.join();
    }
}

/* 获取当前任务队列带执行任务数量 */
size_t ThreadPool::WaitRunTaskCount() const
{
    std::unique_lock<std::mutex> lock(mtx);
    return tasks.size();
}

test.cpp

复制代码
/*
 * 变更历史: 
 * 2026-05-09 cxb 创建文件
 */

/*
 * @file test.cpp
 * @brief 
 * 功能:测试线程池
 */


#include <iostream>
#include "ThreadPool.h"

/* 任务 */
int add(int a, int b)
{
    return a + b;
}

int main()
{
    /* 初始化线程池 */
    ThreadPool pool(4, 100);

    /* 提交任务 */
    auto ret1 = pool.SubmitTask(add, 1, 2);
    /* 获取任务返回值 */
    std::cout << "Result: " << ret1.get() << std::endl;

    /* 提交任务 */
    auto ret2 = pool.SubmitTask([](){
        std::cout << "test ThreadPool" << std::endl;
    });
    /* 获取任务返回值 */
    ret2.get();

    return 0;
}

run.sh

复制代码
#
#   简介:线程池测试编译测试脚本
#   平台:linux
#   可执行程序:thread
#   测试log:thread.log
#

#!/bin/bash

g++ test.cpp ThreadPool.cpp -o thread -lpthread -std=c++11 

echo "====================$(date)=====================" >> thread.log

./thread >> thread.log

thread.log

复制代码
====================2026年 05月 09日 星期六 21:17:31 CST=====================
Result: 3
test ThreadPool
相关推荐
IMPYLH1 小时前
Linux 的 uname 命令
linux·运维·服务器·数据库·bash
量子炒饭大师1 小时前
【Linux系统编程】Cyberpunk在霓虹丛林中构建堡垒 ——【Linux环境配置 与 基础指令】
linux·运维·microsoft·linux指令
LinuxGeek10241 小时前
Linux 内核 “Copy Fail” 漏洞(CVE-2026-31431)修复方案
linux·运维·服务器
月白风清江有声1 小时前
下载电影开字幕(不是实时的ployer)
linux·学习
minji...1 小时前
Linux 网络基础(三)HTTP的请求方法(GET/POST),HTTP表单、临时和永久重定向状态码、Cookie、查询参数、Web根目录
linux·运维·服务器·网络·c++·http
小茬粥1 小时前
COLT_CMDB_nvidia_gpu_20260508.sh
linux·服务器·windows
鱼很腾apoc1 小时前
【学习篇】第18期 C++模板
c语言·c++
流浪0011 小时前
Linux基础篇(二)轻松掌握入门级指令
linux·运维·服务器