c++线程池实现包含阻塞任务队列、工作线程组、停止标志、条件变量和互斥锁;支持任意可调用对象入队,返回future获取结果,析构时安全等待并停止所有线程。

用C++实现一个轻量、实用的线程池,核心是管理一组复用的工作线程,配合任务队列和同步机制。下面是一个基于 std::Thread、std::queue、std::mutex 和 std::condition_variable 的简洁实现,支持任意可调用对象(Lambda、函数指针、bind等),并具备安全停止功能。
线程池的基本结构设计
一个最小可用线程池需包含:
- 一个阻塞任务队列(线程安全)
- 一组运行中的工作线程
- 控制生命周期的标志(如
m_stop) - 用于唤醒等待线程的条件变量
- 保护共享数据的互斥锁
完整可运行代码示例
以下为 C++11 及以上兼容的实现(无需第三方库):
立即学习“C++免费学习笔记(深入)”;
#include #include #include #include #include #include #include #include class ThreadPool { public: explicit ThreadPool(size_t threads) : m_stop(false) { for (size_t i = 0; i < threads; ++i) { m_workers.emplace_back([this] { while (true) { std::function task; { std::unique_lock lock(m_queue_mutex); m_condition.wait(lock, [this] { return m_stop || !m_tasks.empty(); }); if (m_stop && m_tasks.empty()) return; task = std::move(m_tasks.front()); m_tasks.pop(); } task(); } }); } }
templatezuojiankuohaophpcnclass F, class... Argsyoujiankuohaophpcn auto enqueue(F&& f, Args&&... args) -youjiankuohaophpcn std::futurezuojiankuohaophpcntypename std::result_ofzuojiankuohaophpcnF(Args...) youjiankuohaophpcn::typeyoujiankuohaophpcn { using return_type = typename std::result_ofzuojiankuohaophpcnF(Args...) youjiankuohaophpcn::type; auto task = std::make_sharedzuojiankuohaophpcnstd::packaged_taskzuojiankuohaophpcnreturn_type()youjiankuohaophpcnyoujiankuohaophpcn( std::bind(std::forwardzuojiankuohaophpcnFyoujiankuohaophpcn(f), std::forwardzuojiankuohaophpcnArgsyoujiankuohaophpcn(args)...) ); std::futurezuojiankuohaophpcnreturn_typeyoujiankuohaophpcn res = task-youjiankuohaophpcnget_future(); { std::unique_lockzuojiankuohaophpcnstd::mutexyoujiankuohaophpcn lock(m_queue_mutex); if (m_stop) throw std::runtime_error("enqueue on stopped ThreadPool"); m_tasks.emplace([task]() { (*task)(); }); } m_condition.notify_one(); return res; } ~ThreadPool() { { std::unique_lockzuojiankuohaophpcnstd::mutexyoujiankuohaophpcn lock(m_queue_mutex); m_stop = true; } m_condition.notify_all(); for (std::thread &t : m_workers) { if (t.joinable()) t.join(); } }
private: std::vector<:thread> m_workers; std::queue<:function>> m_tasks; std::mutex m_queue_mutex; std::condition_variable m_condition; bool m_stop; };
如何使用线程池提交任务
支持无返回值和带返回值两种常见场景:
无返回值任务:
ThreadPool pool(4); pool.enqueue([]{ std::cout << "Hello from threadn"; });
带返回值任务(自动获取 future):
auto result = pool.enqueue([](int a, int b) { return a + b; }, 10, 20); std::cout << result.get() << "n"; // 输出 30
捕获局部变量的 lambda:
int x = 42; auto fut = pool.enqueue([x]{ return x * 2; }); std::cout << fut.get() << "n"; // 输出 84
注意事项与改进方向
该实现在教学和中小型项目中足够稳健,但生产环境可考虑:
- 任务优先级支持(改用优先队列)
- 空闲线程超时回收(避免常驻过多线程)
- 任务取消机制(需在 callable 中主动检查中断标记)
- 更细粒度的异常传播(当前异常会终止 worker 线程)
- 使用
std::jthread(C++20)简化析构时 join 逻辑
不复杂但容易忽略:确保所有任务对象在线程池销毁前完成,或显式等待 future;避免在任务中持有线程池自身的引用,防止循环依赖和析构死锁。