C++ 入门第25天:线程池(Thread Pool)基础
往期回顾:
C++ 学习第22天:智能指针与异常处理-CSDN博客
C++ 入门第23天:Lambda 表达式与标准库算法入门-CSDN博客
C++ 入门第24天:C++11 多线程基础-CSDN博客
C++ 入门第25天:线程池(Thread Pool)基础
前言
线程池 是一种高效的线程管理机制,通过复用一组线程来处理多个任务,避免频繁创建和销毁线程的开销。线程池在高并发场景中尤为重要,是现代程序开发中提升性能和资源利用率的重要工具。
今天,我们将学习线程池的基础知识,并实现一个简单的线程池。
1. 什么是线程池?
线程池的核心思想是提前创建一组线程,将任务放入队列中,线程从队列中取出任务并执行。当任务完成后,线程不会销毁,而是返回池中等待下一个任务。
线程池的优点:
- 降低线程创建和销毁的开销。
- 控制线程的并发数量,避免资源过度消耗。
- 提高任务处理效率。
2. 线程池的基本结构
线程池的实现主要包括以下几个部分:
- 任务队列:存储需要执行的任务。
- 工作线程:从任务队列中取出任务并执行。
- 任务提交接口:提供给用户提交任务的功能。
3. 使用 std::async
实现简单线程池
std::async
是 C++11 提供的一种异步任务工具,可以用来实现简单的线程池。
示例代码
#include <iostream>
#include <future>
#include <vector>
using namespace std;// 一个简单的任务函数
int task(int n) {cout << "Task " << n << " is running in thread " << this_thread::get_id() << endl;return n * n;
}int main() {// 存储 future 对象的容器vector<future<int>> results;// 提交多个任务for (int i = 1; i <= 5; i++) {results.push_back(async(launch::async, task, i));}// 获取任务的执行结果for (auto &result : results) {cout << "Result: " << result.get() << endl;}return 0;
}
输出结果(线程 ID 可能不同):
Task 1 is running in thread 12345
Task 2 is running in thread 12346
Task 3 is running in thread 12347
Task 4 is running in thread 12348
Task 5 is running in thread 12349
Result: 1
Result: 4
Result: 9
Result: 16
Result: 25
4. 手动实现线程池
为了更深入理解线程池,我们可以手动实现一个简单的线程池。
4.1 线程池的代码实现
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>
using namespace std;class ThreadPool {
public:ThreadPool(size_t num_threads);~ThreadPool();// 提交任务到线程池template <class F, class... Args>auto enqueue(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::type>;private:vector<thread> workers; // 工作线程queue<function<void()>> tasks; // 任务队列mutex queue_mutex; // 互斥锁condition_variable condition; // 条件变量bool stop; // 停止标志
};// 构造函数:创建指定数量的线程
ThreadPool::ThreadPool(size_t num_threads) : stop(false) {for (size_t i = 0; i < num_threads; ++i) {workers.emplace_back([this] {while (true) {function<void()> task;{unique_lock<mutex> lock(this->queue_mutex);this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });if (this->stop && this->tasks.empty()) return;task = move(this->tasks.front());this->tasks.pop();}task();}});}
}// 提交任务到线程池
template <class F, class... Args>
auto ThreadPool::enqueue(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::type> {using return_type = typename result_of<F(Args...)>::type;auto task = make_shared<packaged_task<return_type()>>(bind(forward<F>(f), forward<Args>(args)...));future<return_type> res = task->get_future();{lock_guard<mutex> lock(queue_mutex);if (stop) throw runtime_error("enqueue on stopped ThreadPool");tasks.emplace([task]() { (*task)(); });}condition.notify_one();return res;
}// 析构函数:停止所有线程
ThreadPool::~ThreadPool() {{lock_guard<mutex> lock(queue_mutex);stop = true;}condition.notify_all();for (thread& worker : workers) {if (worker.joinable()) worker.join();}
}
4.2 使用线程池
#include <iostream>
#include "ThreadPool.h" // 假设前面的代码在 ThreadPool.h 中
using namespace std;int main() {// 创建一个包含 4 个线程的线程池ThreadPool pool(4);// 提交任务并获取结果auto result1 = pool.enqueue([](int a, int b) { return a + b; }, 2, 3);auto result2 = pool.enqueue([](int n) { return n * n; }, 5);cout << "Result1: " << result1.get() << endl;cout << "Result2: " << result2.get() << endl;return 0;
}
输出结果:
Result1: 5
Result2: 25
结语
以上就是 C++ 11 多线程中线程池的基础知识点了。线程池是现代多线程编程的重要工具,线程池的原理:通过复用线程和任务队列,提高性能和资源利用率。std::async
的简单实现:快速实现异步任务处理。同时我们手动从零开始实现了一个功能完整的线程池。线程池可以大幅提升程序的效率,但在实际使用中,需要注意线程的同步和资源管理问题。
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!
相关文章:
C++ 入门第25天:线程池(Thread Pool)基础
往期回顾: C 学习第22天:智能指针与异常处理-CSDN博客 C 入门第23天:Lambda 表达式与标准库算法入门-CSDN博客 C 入门第24天:C11 多线程基础-CSDN博客 C 入门第25天:线程池(Thread Pool)基础 前…...

微信小程序中的 storage(本地存储)和内存是两个完全不同的存储区域
这是一个非常关键且容易混淆的概念 既然 this.globalData.appId appId 是将 appId 存储在内存中,为什么微信小程序中的 wx.getStorage 和 wx.setStorage(本地存储)中没有 appId,并且您提出了一个非常重要的疑问:stor…...

WLAN基本原理与配置
一、WLAN概述 二、WLAN的基本概念 AC与Fit AP的组网架构: 1.二层组网 AC和Fit AP在一个广播域中 2.三层组网 AC和Fit AP需要跨三层通信 CAPWAP(无线接入点控制和配置协议): 该协议定义了如何对AP进行管理、业务配置&#…...

KaliLinux 2022.1安装和相关配置
一、安装系统和设置中文 (一)下载安装KaliLInux2022.1 以直接下载虚拟机映像文件为例,下载地址:https://www.kali.org/get-kali/#kali-virtual-machines,下载完成后直接解压,再用VMware打开后开机&#x…...

HarmonyOS开发:ArkTS初识
ArkTS基本语法 ArkTS语言简介 ArkTS是鸿蒙生态的应用开发语言。基本语法风格与TypeScript(简称TS)相似,在TS的生态基础上进一步扩展,继承了TS的所有特性,是TS的超集。 基本语法概述 扩展能力 基础语法:…...
Unity的四种数据持久化方式
目录 什么是数据持久化 数据持久化之PlayerPrefs 概述 API及用法 电脑中存放的位置 优缺点 主要用处 封装PlayerPrefs 数据持久化之XML XML是什么 读取XML信息 C#读取XML的方法有几种 读取xml文件信息 读取元素和属性信息 总结 写入XML信息 选择存储目录 存储…...

机器学习笔记 - 单幅图像深度估计的最新技术
1、深度估计简述 单眼深度估计是一项计算机视觉任务,AI 模型从单个图像中预测场景的深度信息。模型估计场景中对象从一个照相机视点的距离。单目深度估计已广泛用于自动驾驶、机器人等领域。深度估计被认为是最困难的计算机视觉任务之一,因为它要求模型理解对象及其深度信息之…...

Postman接口测试02|接口用例设计
目录 六、接口用例设计 1、接口测试的测试点(测试维度) 1️⃣功能测试 2️⃣性能测试 3️⃣安全测试 2、设计方法与思路 3、单接口测试用例 4、业务场景测试用例 1️⃣分析测试点 2️⃣添加员工 3️⃣查询员工、修改员工 4️⃣删除员工、查询…...
C#语言的学习路线
C#语言的学习路线 C#(读作“C Sharp”)是一种由微软开发的现代编程语言,具有强大的功能和灵活性,广泛应用于桌面应用程序、Web开发、游戏开发以及企业级应用等多个领域。无论你是编程新手还是有一定基础的开发者,掌握…...
双目的一些文章学习
文章1 PSMNet https://arxiv.org/pdf/1803.08669PSMNet文章博客PSMNet文章中牵涉到的一些知识,空洞卷积,SPPNet网络,计算视差时用soft argmin代替argmin文章中引入了空洞卷积和SPPNet网络来融合多尺度的信息,又引入3D卷积来增加模…...
开源模型应用落地-qwen2-7b-instruct-LoRA微调合并-ms-swift-单机单卡-V100(十三)
一、前言 本篇文章将使用ms-swift去合并微调后的模型权重,通过阅读本文,您将能够更好地掌握这些关键技术,理解其中的关键技术要点,并应用于自己的项目中。 二、术语介绍 2.1. LoRA微调 LoRA (Low-Rank Adaptation) 用于微调大型语言模型 (LLM)。 是一种有效的自适应策略,…...

【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 一、类的声明和使用 1. 类的声明基础 2. 类的访问控制 3. 类的使用 二、类的声明和对象的声明 1. 类声明中的函数定义 2. 对象声明的多种方式 三、构造函数和析构函数的执行过程 1. 构造函数 2. 析构函数 实验步骤 测试说明…...

性能测试05|JMeter:分布式、报告、并发数计算、性能监控
目录 一、JMeter分布式 1、应用场景 2、原理 3、分布式相关注意事项 4、分布式配置与运行 二、JMeter报告 1、聚合报告 2、HTML报告 三、并发用户数(线程数)计算 四、JMeter下载第三方插件 五、性能监控 1、Concurrency Thread Group 线程组…...
关于Java面试题大全网站无法访问的解决方案
如果Java面试题大全网站无法访问,你仍然可以通过以下渠道获取高质量的Java面试题资源: 1. 国内网站 牛客网: 网址:https://www.nowcoder.com/特点:提供大量Java面试题和在线编程练习,适合刷题和模拟面试。推…...

CSS进阶和SASS
目录 一、CSS进阶 1.1、CSS变量 1.2、CSS属性值的计算过程 1.3、做杯咖啡 1.4、下划线动画 1.5、CSS中的混合模式(Blending) 二、SASS 2.1、Sass的颜色函数 2.2、Sass的扩展(extend)和占位符(%)、混合(Mixin) 2.3、Sass的数学函数 2.4、Sass的模块化开发 2.5、Sass…...

SwiftUI 撸码常见错误 2 例漫谈
概述 在 SwiftUI 日常撸码过程中,头发尚且还算茂盛的小码农们经常会犯这样那样的错误。虽然犯这些错的原因都很简单,但有时想要快速准确的定位它们却并不容易。 况且这些错误还可能在模拟器和 Xcode 预览(Preview)表现的行为不甚…...
JavaScript系列(9)-- Set数据结构专题
JavaScript Set数据结构专题 🎲 在前八篇文章中,我们探讨了JavaScript的语言特性、ECMAScript标准、引擎工作原理、数值类型、字符串处理、Symbol类型、Object高级特性和Array高级操作。今天,让我们深入了解JavaScript中的Set数据结构。Set是…...

开发培训-慧集通(iPaaS)集成平台脚本开发Groovy基础培训视频
Groovy是一种基于Java虚拟机(JVM)的敏捷开发语言,结合了Python、Ruby和Smalltalk的许多强大特性。它旨在提高开发者的生产力,通过简洁、熟悉且易于学习的语法,Groovy能够与Java代码无缝集成,并提供强大…...

【软考网工笔记】计算机基础理论与安全——网络规划与设计
HFC 混合光纤同轴电缆网 HFC: Hybrid Fiber - Coaxial 的缩写,即混合光纤同轴电缆网。是一种经济实用的综合数字服务宽带网接入技术。 HFC 通常由光纤干线、同轴电缆支线和用户配线网络三部分组成,从有线电视台出来的节目信号先变成光信号在干线上传输…...

【设计模式】 基本原则、设计模式分类
设计模式 设计模式是软件工程中的一种通用术语,指的是针对特定问题的经过实践验证的解决方案。设计模式并不是最终的代码实现,而是描述了如何解决某一类问题的思路和方法。 如果熟悉了设计模式,当遇到类似的场景,我们可以快速地…...

【动手学MCP从0到1】2.1 SDK介绍和第一个MCP创建的步骤详解
SDK介绍和第一个MCP 1. 安装SDK2. MCP通信协议3. 基于stdio通信3.1 服务段脚本代码3.2 客户端执行代码3.2.1 客户端的初始化设置3.2.2 创建执行进行的函数3.2.3 代码优化 4. 基于SSE协议通信 1. 安装SDK 开发mcp项目,既可以使用Anthropic官方提供的SDK,…...

Vert.x学习笔记-Verticle原理解析
Vert.x学习笔记 一、设计理念:事件驱动的组件化模型二、生命周期管理三、部署方式与策略四、通信机制:事件总线(Event Bus)五、底层实现原理六、典型应用场景七、Verticle与EventLoop的关系1、核心关系:一对一绑定与线…...
2025 Java面试大全技术文章(面试题1)
数据类型与包装类 问题:Java中基本数据类型与包装类的区别是什么?自动装箱与拆箱的底层原理? 答案: 基本数据类型(如int、double)直接存储值,包装类(如Integer、Double)…...

HTTP协议完全指南:从请求响应到HTTPS安全机制
文章目录 一、HTTP协议中的基本概念1.HTTP协议介绍(1)协议(2)传输(3)超文本 2.统一资源定位符(URL) 二、HTTP协议中的请求和响应1.HTTP客户端请求消息(1)请求…...

优化 Spring Boot API 性能:利用 GZIP 压缩处理大型有效载荷
引言 在构建需要处理和传输大量数据的API服务时,响应时间是一个关键的性能指标。一个常见的场景是,即使后端逻辑和数据库查询已得到充分优化,当API端点返回大型数据集(例如,数千条记录的列表)时࿰…...
day42 简单CNN
目录 一、从图像分类任务谈起 二、CNN架构解剖实验室 2.1 卷积层:空间特征的魔法师 2.2 归一化层:加速收敛的隐形推手 2.3 激活函数:非线性的灵魂 三、工程实践避坑指南 3.1 数据增强工程 3.2 调度器工程实战 四、典型问题排查手册 …...

大语言模型评测体系全解析(上篇):基础框架与综合评测平台
文章目录 一、评测体系的历史演进与技术底座(一)发展历程:从单任务到全维度评测1. 2018年前:单数据集时代的萌芽2. 2019-2023年:多任务基准的爆发式增长3. 2024年至今:动态化、场景化、多模态体系成型关键节…...
Linux 命令全讲解:从基础操作到高级运维的实战指南
Linux 命令全讲解:从基础操作到高级运维的实战指南 前言 Linux 作为开源操作系统的代表,凭借其稳定性、灵活性和强大的定制能力,广泛应用于服务器、云计算、嵌入式设备等领域。对于开发者、运维工程师甚至普通用户而言,熟练掌握…...
Python玩转自动驾驶仿真数据生成:打造你的智能“路测场”
Python玩转自动驾驶仿真数据生成:打造你的智能“路测场” 说到自动驾驶,很多人第一时间想到的是那些造车新势力、激光雷达、传感器、深度学习模型……确实,这些都是自动驾驶的核心硬核。但我今天想和你聊聊一个“幕后功臣”——仿真数据生成。没错,自动驾驶离不开大数据,更…...

ElasticStack技术之logstash介绍
一、什么是Logstash Logstash 是 Elastic Stack(ELK Stack)中的一个开源数据处理管道工具,主要用于收集、解析、过滤和传输数据。它支持多种输入源,如文件、网络、数据库等,能够灵活地对数据进行处理,比如…...