C++11实战:手把手教你写个线程池
自从C11 直接内置线程库后再也不用靠操作系统API裸奔写并发了但是呢这标准库给的多线程支持还是太基础了想整点高级活儿比如线程池、信号量啥的还得咱自己动手丰衣足食。比如面试聊到线程池面试官一问“说说原理”你张口就来“任务队列 线程队列循环分配呗”听着贼溜可真让你写代码立马原地懵圈——因为C的std::thread一旦跑完函数就自爆了根本没法复用那咋整别慌咱有妙招让每个线程启动后不是干一票就跑而是蹲在调度函数里死循环——有活就干没活就睡直到线程池喊“收工”才滚蛋这不就实现线程复用了嘛简直比小区门口的共享单车还环保整个线程池就俩核心积木任务队列Task Queue谁先来谁先干FIFO安排得明明白白。线程大军Thread Pool一群打工人24小时待命随时准备搬砖。而这俩之间的配合妥妥一个生产者-消费者模型——主线程往队列里塞任务生产者工作线程从队列里抢任务消费者。为了防止大家抢成一团乱麻咱祭出两大法宝一把mutex锁保证同一时间只有一个人能动队列一个条件变量condition_variable队列空了别傻等直接睡觉等有新任务来了我“啪”一下把你叫醒积木1SafeQueue —— 线程安全的任务队列你以为直接拿个std::queue就能上战场Too young多线程环境下它脆得跟薯片一样。所以咱得给它套上盔甲——封装成SafeQueue原理贼简单所有操作都先抢锁抢到才能动队列。你看这代码enqueue、dequeue、empty、size哪个不是裹着unique_lock出场就像你去ATM取钱门一关别人只能干瞪眼// thread_pool.h 里的 SafeQueue 实现 template typename T class SafeQueue { private: std::queueT m_queue; // 利用模板函数构造队列 std::mutex m_mutex; // 访问互斥信号量 public: SafeQueue() {} SafeQueue(SafeQueue other) {} ~SafeQueue() {} bool empty() { std::unique_lockstd::mutex lock(m_mutex); return m_queue.empty(); } int size() { std::unique_lockstd::mutex lock(m_mutex); return m_queue.size(); } // 队列添加元素 void enqueue(T t) { std::unique_lockstd::mutex lock(m_mutex); m_queue.emplace(t); // 安全入队稳如老狗 } // 队列取出元素 bool dequeue(T t) { std::unique_lockstd::mutex lock(m_mutex); if (m_queue.empty()) return false; t std::move(m_queue.front()); // 右值引用性能拉满 m_queue.pop(); return true; } };看明白没加锁 → 操作 → 自动解锁三步走安全又高效这SafeQueue就是咱线程池的“任务快递柜”谁来取件都得排队刷脸积木2ThreadPool —— 真正的“包工头”提交任务submit()给你安排得明明白白你想往线程池扔个lambda成员函数普通函数带参数带返回值统统接得住秘诀就是C11的语法糖三件套可变模板参数Args...参数多少都不怕尾置返回类型- decltype(...)自动推导返回值类型再也不用手动写typename std::result_of...::type那种绕死人的玩意儿完美转发std::forward左值右值原样传递绝不掉帧重点来了为了让任务能异步执行并拿到结果咱用std::packaged_task把函数打包再用shared_ptr包一层方便复制最后塞进一个void()的lambda里丢进队列。为啥要转成void()因为任务队列只认统一接口就像快递柜不管你寄的是手机还是泡面都得装进标准箱子里// Submit a function to be executed asynchronously by the pool template typename F, typename... Args auto submit(F f, Args ...args) - std::futuredecltype(f(args...)) { // 1. 绑定函数和参数 → func() std::functiondecltype(f(args...))() func std::bind(std::forwardF(f), std::forwardArgs(args)...); // 2. 打包成packaged_task带返回值的异步任务 auto task_ptr std::make_sharedstd::packaged_taskdecltype(f(args...))()(func); // 3. 包装成void()函数塞进队列 std::functionvoid() warpper_func [task_ptr]() { (*task_ptr)(); }; // 4. 队列通用安全封包函数并压入安全队列 m_queue.enqueue(warpper_func); // 5. 唤醒一个等待中的线程 m_conditional_lock.notify_one(); // 6. 返回future让你随时能查结果 return task_ptr-get_future(); }此时你看到decltype(f(args...))脑壳是不是嗡嗡的。别慌这其实就是告诉编译器“兄弟你先看看f(args...)返回啥类型我就按那个类型返回std::future”——智能推导省心省力内置打工人ThreadWorker每个线程启动后就化身ThreadWorker死循环干活检查线程池是否shutdown没关就继续加锁看队列有没有活没有就wait()睡觉有活赶紧dequeue出来解锁然后猛干class ThreadWorker // 内置线程工作类 { private: int m_id; // 工作id ThreadPool *m_pool; // 所属线程池 public: ThreadWorker(ThreadPool *pool, const int id) : m_pool(pool), m_id(id) {} void operator()() { std::functionvoid() func; bool dequeued; while (!m_pool-m_shutdown) { { std::unique_lockstd::mutex lock(m_pool-m_conditional_mutex); // 队列空了睡觉 if (m_pool-m_queue.empty()) { m_pool-m_conditional_lock.wait(lock); } // 抢单 dequeued m_pool-m_queue.dequeue(func); } if (dequeued) func(); // 干活 } } };注意那个wait(lock)——它会在等待时自动释放锁等被唤醒后再重新加锁。这设计简直绝了既省CPU又防死锁堪称线程界的“节能睡眠模式”完整线程池代码直接复制就能跑来上主菜下面这份代码就是咱亲手搓出来的C11线程池全家桶包含所有细节连构造函数删除都给你安排明白了防拷贝防移动专治各种手滑// thread_pool.h #ifndef THREAD_POOL_H #define THREAD_POOL_H #include mutex #include queue #include functional #include future #include thread #include utility #include vector template typename T class SafeQueue { private: std::queueT m_queue; std::mutex m_mutex; public: SafeQueue() {} SafeQueue(SafeQueue other) {} ~SafeQueue() {} bool empty() { std::unique_lockstd::mutex lock(m_mutex); return m_queue.empty(); } int size() { std::unique_lockstd::mutex lock(m_mutex); return m_queue.size(); } void enqueue(T t) { std::unique_lockstd::mutex lock(m_mutex); m_queue.emplace(t); } bool dequeue(T t) { std::unique_lockstd::mutex lock(m_mutex); if (m_queue.empty()) return false; t std::move(m_queue.front()); m_queue.pop(); return true; } }; class ThreadPool { private: class ThreadWorker { private: int m_id; ThreadPool *m_pool; public: ThreadWorker(ThreadPool *pool, const int id) : m_pool(pool), m_id(id) {} void operator()() { std::functionvoid() func; bool dequeued; while (!m_pool-m_shutdown) { { std::unique_lockstd::mutex lock(m_pool-m_conditional_mutex); if (m_pool-m_queue.empty()) { m_pool-m_conditional_lock.wait(lock); } dequeued m_pool-m_queue.dequeue(func); } if (dequeued) func(); } } }; bool m_shutdown; SafeQueuestd::functionvoid() m_queue; std::vectorstd::thread m_threads; std::mutex m_conditional_mutex; std::condition_variable m_conditional_lock; public: ThreadPool(const int n_threads 4) : m_threads(std::vectorstd::thread(n_threads)), m_shutdown(false) {} ThreadPool(const ThreadPool ) delete; ThreadPool(ThreadPool ) delete; ThreadPool operator(const ThreadPool ) delete; ThreadPool operator(ThreadPool ) delete; void init() { for (int i 0; i m_threads.size(); i) { m_threads.at(i) std::thread(ThreadWorker(this, i)); } } void shutdown() { m_shutdown true; m_conditional_lock.notify_all(); // 全员下班 for (int i 0; i m_threads.size(); i) { if (m_threads.at(i).joinable()) { m_threads.at(i).join(); } } } template typename F, typename... Args auto submit(F f, Args ...args) - std::futuredecltype(f(args...)) { std::functiondecltype(f(args...))() func std::bind(std::forwardF(f), std::forwardArgs(args)...); auto task_ptr std::make_sharedstd::packaged_taskdecltype(f(args...))()(func); std::functionvoid() warpper_func [task_ptr]() { (*task_ptr)(); }; m_queue.enqueue(warpper_func); m_conditional_lock.notify_one(); return task_ptr-get_future(); } }; #endif测试样例让线程池动起来光说不练假把式下面这段测试代码直接验证咱的线程池能不能扛住高并发// test.cpp #include iostream #include random #include thread_pool.h std::random_device rd; std::mt19937 mt(rd()); std::uniform_int_distributionint dist(-1000, 1000); auto rnd std::bind(dist, mt); void simulate_hard_computation() { std::this_thread::sleep_for(std::chrono::milliseconds(2000 rnd())); } void multiply(const int a, const int b) { simulate_hard_computation(); std::cout a * b a * b std::endl; } void multiply_output(int out, const int a, const int b) { simulate_hard_computation(); out a * b; std::cout a * b out std::endl; } int multiply_return(const int a, const int b) { simulate_hard_computation(); return a * b; } void example() { ThreadPool pool(3); // 3个打工人 pool.init(); // 开工 // 提交30个乘法任务 for (int i 1; i 3; i) for (int j 1; j 10; j) pool.submit(multiply, i, j); // 带输出参数的任务 int output_ref; auto future1 pool.submit(multiply_output, std::ref(output_ref), 5, 6); future1.get(); // 等结果 std::cout Last result (by ref): output_ref std::endl; // 带返回值的任务 auto future2 pool.submit(multiply_return, 5, 3); int res future2.get(); std::cout Last result (by return): res std::endl; pool.shutdown(); // 收工 } int main() { example(); return 0; }跑起来你会发现30个乘法任务并发执行输出顺序乱七八糟正常但每个结果都对还能通过future.get()同步拿结果——异步提交 同步获取灵活得一批深耕 C/C 开发的小伙伴如果你不知选择哪个方向就业发展纠结 C 的学习价值与行业前景不妨看为什么很多人劝退学 C但大厂核心岗位还是要 C帮你理清行业逻辑找准发展方向如果你想深耕Linux C/C后端却没有清晰的学习路径【大厂标准】Linux C/C 后端进阶学习路线给你大厂级的进阶指南少走弯路如果你想入局音视频流媒体领域零基础不知从何下手音视频流媒体高级开发 - 学习路线精准拆解学习重点搭建完整知识体系如果你瞄准桌面开发/嵌入式开发想掌握 C Qt 核心技能C Qt 学习路线一条龙桌面开发 嵌入式开发一站式教你从入门到实战如果你想挑战Linux内核开发追求硬核技术提升Linux 内核学习指南硬核修炼手册带你吃透内核底层突破技术瓶颈如果你正备战面试急需刷题提分C/C 高频八股文面试题 1000 题三直击面试高频考点帮你快速查漏补缺如果你面试总被手撕代码难住尤其是线程池相关考点手撕线程池C 程序员的能力试金石手把手教你实现核心逻辑夯实编程功底如果你着急找工作、无面试机会、拿不到offer分不清是技术欠缺还是简历问题更要从这些文章里找准问题核心针对性提升快速突破求职瓶颈总结线程池这东西说白了就是管理任务和线程的配对掌握核心原理剩下的都是语法糖这套线程池虽然只有百来行但五脏俱全支持任意函数、任意参数、返回值获取、线程安全、资源自动回收……作为C并发入门真的很合适不过老铁们注意啊实际项目中还得考虑异常安全、任务拒绝策略、动态扩缩容啥的。但作为基础框架它已经把核心思想给你焊死了——复用线程 安全队列 条件唤醒三大心法缺一不可

相关新闻

COMSOL声学—超声波无损检测(三维) 模型介绍:本模型主要利用压力声学、静电、固体力学以及...

COMSOL声学—超声波无损检测(三维) 模型介绍:本模型主要利用压力声学、静电、固体力学以及...

COMSOL声学—超声波无损检测(三维) 模型介绍:本模型主要利用压力声学、静电、固体力学以及压电效应、声结构耦合边界多物理场6个模块。 本模型包括压电单元(PZT-5H)和被检测材料(樟子松)两个部分…

2026/7/4 16:42:28 阅读更多 →
【小程序毕设源码分享】基于springboot+小程序的高校讲座信息APP的设计与实现(程序+文档+代码讲解+一条龙定制)

【小程序毕设源码分享】基于springboot+小程序的高校讲座信息APP的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/3 7:16:18 阅读更多 →
【小程序毕设全套源码+文档】基于Android的地球村共享书屋平台的设计与实现(丰富项目+远程调试+讲解+定制)

【小程序毕设全套源码+文档】基于Android的地球村共享书屋平台的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/5/17 3:26:39 阅读更多 →

最新新闻

AI Agent Skills开发实战:代码审查与CI/CD集成

AI Agent Skills开发实战:代码审查与CI/CD集成

1. 项目概述:AI Agent Skills在开发中的实战价值第一次在项目中引入Agent Skills时,我正面临着一个典型的技术困境:团队需要处理大量重复性代码审查工作,但人工检查既耗时又容易遗漏细节。当时偶然发现Anthropic开源的Agent Skill…

2026/7/5 11:25:23 阅读更多 →
Unlimited-OCR长文档解析:R-SWA机制原理与生产部署指南

Unlimited-OCR长文档解析:R-SWA机制原理与生产部署指南

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你正在处理一份几十页的PDF报告、一本扫描版电子书,或者一份复杂的学术论文,想把它们转换成可编辑、可搜索…

2026/7/5 11:23:22 阅读更多 →
遗传算法优化BP神经网络:从理论到实践(附Python源码)

遗传算法优化BP神经网络:从理论到实践(附Python源码)

1. 为什么需要遗传算法优化BP神经网络?BP神经网络作为最基础的前馈神经网络,在函数拟合、分类预测等任务中表现优异。但我在实际项目中发现,传统BP算法存在两个致命缺陷:一是初始权值随机生成,训练结果不稳定&#xff…

2026/7/5 11:23:22 阅读更多 →
Python实现NLP中文文本自动摘要系统详解

Python实现NLP中文文本自动摘要系统详解

1. 项目概述这个NLP中文自动生成文本摘要系统是一个基于Python开发的完整解决方案,包含源码、详细技术报告和系统讲解。它能够自动处理中文文本,生成简洁准确的摘要内容,适用于新闻聚合、论文综述、商业报告等多种场景。系统采用先进的自然语…

2026/7/5 11:21:22 阅读更多 →
2026年MacBook Neo用户转向Windows笔记本:AI PC选购与迁移全指南

2026年MacBook Neo用户转向Windows笔记本:AI PC选购与迁移全指南

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你正在考虑入手一台 MacBook Neo,或者已经习惯了苹果生态,但又被 Windows 阵营近两年在 AI、性能和生态上…

2026/7/5 11:21:22 阅读更多 →
Python 实现最优化 6 大经典算法:梯度下降、牛顿法与罚函数法实战对比

Python 实现最优化 6 大经典算法:梯度下降、牛顿法与罚函数法实战对比

Python 实现最优化 6 大经典算法:梯度下降、牛顿法与罚函数法实战对比在机器学习和工程优化领域,最优化算法扮演着至关重要的角色。本文将深入探讨六种经典优化算法的 Python 实现,并通过 Rosenbrock 函数这一经典测试案例,对比分…

2026/7/5 11:19:22 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻