news 2026/8/23 22:26:23

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/8/21 18:33:30

什么是WLAN

文章目录 WLAN的优势WLAN和Wi-Fi有什么不同WLAN安全吗WLAN的漫游WLAN的基本元素WLAN的网络类型WLAN是怎么工作的 无线局域网WLAN&#xff08;Wireless Local Area Network&#xff09;是一种无线计算机网络&#xff0c;使用无线信道代替有线传输介质连接两个或多个设备形成一个…

作者头像 李华
网站建设 2026/8/23 1:26:38

小程序计算机毕设之基于微信小程序的智慧校园平台的设计与实现基于springboot+小程序的高校校园信息交流平台小程序设计与实现(完整前后端代码+说明文档+LW,调试定制等)

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

作者头像 李华
网站建设 2026/8/21 18:33:28

《P3168 [CQOI2015] 任务查询系统》

题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统&#xff0c;而你被安排完成其中的查询部分。 超级计算机中的任务用三元组 (si​,ei​,pi​) 描述&#xff0c;(si​,ei​,pi​) 表示任务从第 si​ 秒开始&#xff0c;在第 ei​ 秒后结束&#xff08;第 si…

作者头像 李华
网站建设 2026/8/21 18:33:29

【计算机毕业设计案例】基于springboot+vue的微信小程序的智慧校园平台基于springboot+小程序的高校校园信息交流平台小程序设计与实现(程序+文档+讲解+定制)

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

作者头像 李华
网站建设 2026/8/23 15:07:47

小程序毕设选题推荐:基于Springboot+Uniapp的家校通平台微信小程序设计与实现基于springboot+小程序的家校通程序设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】

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

作者头像 李华
网站建设 2026/8/22 19:41:49

【课程设计/毕业设计】基于SpringBoot校园生活服务小程序基于springboot+小程序的高校生活互助平台小程序【附源码、数据库、万字文档】

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

作者头像 李华