0

0

c++如何实现简单的线程池_c++任务队列与线程复用【实战】

穿越時空

穿越時空

发布时间:2026-02-10 11:42:09

|

846人浏览过

|

来源于php中文网

原创

std::thread 不适用于高频小任务,因创建/销毁开销大(10–100 μs)且易触达系统线程数限制;应使用固定线程池+线程安全队列实现复用,配合 std::packaged_task 支持返回值,并注意析构时的同步与生命周期管理。

c++如何实现简单的线程池_c++任务队列与线程复用【实战】

为什么 std::thread 直接创建线程不适用于高频小任务

每次 std::thread 构造 + join()detach() 都涉及系统调用开销,Linux 下一次线程创建/销毁约 10–100 μs;频繁操作会吃掉大量 CPU 时间,且容易触发 Resource temporarily unavailableerrno=11)错误——本质是线程数超 /proc/sys/kernel/threads-max 或进程的 RLIMIT_NPROC 限制。

真正需要的是:固定数量的工作线程长期存活,从共享队列里取任务执行,即「线程复用」。

  • 任务提交方只管 push 到队列,不关心谁执行、何时执行
  • 工作线程用 while (running) { task = queue.pop(); if (task) task(); } 循环消费
  • 必须用 std::mutex + std::condition_variable 同步队列读写和空闲唤醒
  • 避免虚假唤醒:pop 必须在 cv.wait(lock, [&]{ return !queue.empty() || !running; }); 谓词中检查

std::queue 不能直接用于多线程任务队列

std::queue 本身不是线程安全的,即使外层加了锁,其内部的 front() + pop() 是两个独立操作——中间可能被其他线程修改,导致 front() 返回已失效引用或 pop() 崩溃。

正确做法是封装一个线程安全的队列,关键点:

立即学习C++免费学习笔记(深入)”;

  • std::deque 底层(比 std::vector 更适合头删)
  • 提供原子性的 try_pop() 方法:内部完成「判空 → 取值 → 删除」三步并加锁
  • 返回类型建议用 std::optional<:function>>(C++17),或用输出参数 + bool 返回值兼容老标准
  • 不要暴露原始引用,避免外部持有后队列已 pop 导致悬垂

示例片段:

讯飞绘文
讯飞绘文

讯飞绘文:免费AI写作/AI生成文章

下载
template
class thread_safe_queue {
    mutable std::mutex mtx_;
    std::queue q_;
    std::condition_variable cv_;
public:
    void push(T&& x) {
        std::lock_guard lk(mtx_);
        q_.push(std::move(x));
        cv_.notify_one();
    }
    bool try_pop(T& res) {
        std::lock_guard lk(mtx_);
        if (q_.empty()) return false;
        res = std::move(q_.front());
        q_.pop();
        return true;
    }
};

如何让线程池支持带返回值的任务(std::future

原生 std::packaged_task 是最自然的解法:它把任意可调用对象包装成能绑定到 std::future 的任务。线程池不直接存 std::function,而存 std::packaged_task(无返回)或 std::packaged_task(有返回)。

关键细节:

  • 提交任务时:构造 std::packaged_task,调用 get_future() 拿到 std::future,再把 task 移动进队列
  • 工作线程取出 task 后直接调用(task()),此时 future 自动就绪
  • 注意:std::packaged_task 不可拷贝,必须用 std::move 传递;若用 std::function 包一层会丢失 future 关联,绝对不要这么做
  • 如果要统一接口,可定义模板 submit 方法:template auto submit(F&& f, Args&&... args) -> std::future<:invoke_result_t args...>>

关闭线程池时最容易卡死的三个地方

调用 stop() 后,线程池应等待所有正在运行的任务结束,再回收线程。但实际常卡在:

  • 工作线程阻塞在 cv_.wait(),但主线程已设 running = false 并调用 cv_.notify_all() —— 这没问题;问题在于没等所有线程真正退出就析构了 mutex 或 cv,导致未定义行为
  • 任务本身是阻塞操作(如网络 IO、sleep),且未提供取消机制,线程无法响应 running == false 就一直卡着
  • 线程 join 顺序不对:主线程先析构了任务队列对象,但某个工作线程还在访问它(即使已跳出循环,也可能刚 pop 完还没执行完)

安全做法:析构函数中先置 running = falsecv_.notify_all(),再对每个 std::thread 调用 join();所有线程对象、互斥量、条件变量生命周期必须长于工作线程函数作用域。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

165

2023.12.20

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

803

2023.08.22

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

100

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

668

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

555

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

205

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

180

2023.11.23

TensorFlow2深度学习模型实战与优化
TensorFlow2深度学习模型实战与优化

本专题面向 AI 与数据科学开发者,系统讲解 TensorFlow 2 框架下深度学习模型的构建、训练、调优与部署。内容包括神经网络基础、卷积神经网络、循环神经网络、优化算法及模型性能提升技巧。通过实战项目演示,帮助开发者掌握从模型设计到上线的完整流程。

0

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9万人学习

C 教程
C 教程

共75课时 | 4.6万人学习

C++教程
C++教程

共115课时 | 16.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号