news 2026/6/10 16:45:52

C++11实现线程池

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++11实现线程池

这是一个线程池实现,结合了多个异步编程示例。让我详细解释每个部分:

整体结构

代码展示了多种 C++11 异步编程技术的用法,最后实现了一个完整的线程池。

各部分详解

1.第一部分:std::async 的基本用法

void task(const char* name) { std::cout << name << " 开始执行,线程ID: " << std::this_thread::get_id() << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << name << " 完成" << std::endl; }
  • 演示了std::async的两种启动策略:

    • std::launch::async: 立即在新线程中执行

    • std::launch::deferred: 延迟执行(调用get()时才执行)

2.第二部分:std::future 获取结果

std::future<int> result = std::async(std::launch::async, simpleTask); int value = result.get();
  • 展示了如何通过std::future::get()获取异步任务结果

  • 注意:get()只能调用一次

3.第三部分:std::promise 和 std::future

std::promise<double> prom; auto fut = prom.get_future(); std::thread t(computeSqrt, std::move(prom), 9);
  • std::promise用于在线程间传递结果

  • 可以从 promise 获取 future

  • 可以在另一个线程中设置值或异常

4.第四部分:std::shared_future

std::shared_future<int> sharedFut = prom.get_future().share();
  • 多个线程可以共享同一个 future

  • get()可以多次调用

  • 通过share()从普通 future 创建 shared_future

5.第五部分:std::packaged_task

std::packaged_task<int(int)> task([](int x) { return x * x; }); std::future<int> result = task.get_future(); std::thread worker(std::move(task), 5);
  • 包装可调用对象

  • 可以获取关联的 future

  • 可以传递给线程执行

6.第六部分:任务队列和条件变量

void taskRunner(std::queue<std::packaged_task<int()>>& taskqueue, ...) { while (true) { std::unique_lock<std::mutex> lock(task_mtx); cv.wait(lock, [&taskqueue] { return !taskqueue.empty(); }); // 处理任务 } }
  • 使用std::condition_variable实现线程间通信

  • 工作线程等待任务,有任务时被唤醒

  • 主线程添加任务到队列

7.第七部分:并行计算示例(计算素数)

futures.push_back( std::async(std::launch::async, countPrimes, start, end) ); // 收集结果 int total1 = 0; for (auto& fut : futures) { total1 += fut.get(); }
  • 将大任务拆分成多个子任务

  • 使用std::async并行计算

  • 收集所有结果并汇总

8.第八部分:完整的 ThreadPool 类

这是最重要的部分,实现了一个生产级别的线程池

核心设计
class ThreadPool { private: std::vector<std::thread> workers; // 工作线程 std::queue<std::function<void()>> tasks; // 任务队列 std::mutex queue_mutex; // 队列互斥锁 std::condition_variable condition; // 条件变量 bool stop; // 停止标志 };
关键方法
  1. 构造函数:创建指定数量的工作线程

  2. enqueue 方法:提交任务到线程池

  3. 析构函数:优雅关闭线程池

模板方法 enqueue
template<class F, class... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { // 1. 推导返回类型 using return_type = typename std::result_of<F(Args...)>::type; // 2. 创建 packaged_task auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); // 3. 获取 future std::future<return_type> res = task->get_future(); // 4. 将任务添加到队列 { std::unique_lock<std::mutex> lock(queue_mutex); tasks.emplace([task]() { (*task)(); }); } // 5. 通知一个等待的线程 condition.notify_one(); return res; }
工作线程循环
for (;;) { std::function<void()> task; { std::unique_lock<std::mutex> lock(this->queue_mutex); // 等待条件:线程池停止 或 队列不为空 this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); // 线程池停止且队列为空 -> 退出 if (this->stop && this->tasks.empty()) return; task = std::move(this->tasks.front()); this->tasks.pop(); } task(); // 执行任务 }

9.主函数测试

int main() { const int MAX = 100000000; const int THREADS = 8; ThreadPool pool(8); // 创建线程池 std::vector<std::future<int>> futures; // 拆分任务并提交到线程池 for (int i = 0; i < THREADS; ++i) { int start = i * chunk + 1; int end = (i == THREADS - 1) ? MAX : (i + 1) * chunk; futures.push_back( pool.enqueue(countPrimes, start, end) // 提交任务 ); } // 收集结果 int total1 = 0; for (auto& fut : futures) { total1 += fut.get(); // 阻塞等待结果 } std::cout << "素数总数: " << total1 << std::endl; return 0; }

关键特性总结

  1. 线程安全:使用互斥锁保护共享资源

  2. 任务队列:FIFO 顺序执行任务

  3. 条件变量:高效等待任务

  4. 优雅关闭:析构时等待所有任务完成

  5. 异常安全:任务异常不会影响线程池

  6. 通用接口:支持任意可调用对象

  7. 返回结果:通过std::future获取任务结果

使用场景

  • 需要大量并发执行的小任务

  • 避免频繁创建/销毁线程的开销

  • 控制并发线程数量

  • 实现生产者-消费者模式

这个线程池实现是生产可用的,包含了异常处理、资源管理和优雅关闭等关键特性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 12:46:17

数字图像处理---压缩编码

核心比喻&#xff1a;整理行李箱 你要出远门&#xff0c;但行李箱很小。为了装下所有东西&#xff0c;你必须&#xff1a; 扔掉不必要的东西&#xff08;比如多余的包装盒&#xff09;。 用更高效的方式打包&#xff08;比如把衣服卷起来而不是平铺&#xff09;。 压缩编码…

作者头像 李华
网站建设 2026/6/10 12:46:16

小程序计算机毕设之基于springboot+小程序的自助停车缴费系统小程序的设计与实现基于SpringBoot的停车管理微信小程序系统(完整前后端代码+说明文档+LW,调试定制等)

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

作者头像 李华
网站建设 2026/6/9 17:40:18

小程序毕设项目:基于springboot+小程序的自助停车缴费系统小程序的设计与实现(源码+文档,讲解、调试运行,定制等)

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

作者头像 李华
网站建设 2026/6/9 23:31:10

【计算机毕业设计案例】基于springboot+小程序的自助停车缴费系统小程序基于微信小程序的自助停车缴费系统停车场车位预约(程序+文档+讲解+定制)

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

作者头像 李华
网站建设 2026/6/10 3:09:49

深度解析!提示工程架构师与AI提示系统使用案例

深度解析&#xff01;提示工程架构师与AI提示系统使用案例 一、引言&#xff1a;AI大模型时代&#xff0c;提示工程为何成为“桥梁”&#xff1f; 2023年以来&#xff0c;ChatGPT、GPT-4、Claude 3、Gemini等大模型的爆发&#xff0c;彻底改变了人类与AI交互的方式。但很多人忽…

作者头像 李华
网站建设 2026/6/10 12:46:40

内网共享神器,手机电脑一键互传大文件

软件介绍 今天给各位安利一款超省心的内网共享小工具&#xff0c;它叫 LocalSend&#xff08;注&#xff1a;原文未明确命名&#xff0c;此处按功能特性暂拟名&#xff0c;实际使用时请参考官方名称&#xff09;。这玩意儿比之前提过的"文件共享工具"、"MeFile…

作者头像 李华