C++11 Thead线程和线程池
参考资料:
2、5.lock_guard 与 std::unique_lock-陈子青的编程学习课堂 (seestudy.cn)
3、C++11 多线程编程-小白零基础到手撕线程池_哔哩哔哩_bilibili
一、 C++11 Thead线程库的基本使用
# include <thread>
std::thread t(function_name, args...); // 线程开始运行
t.join() // 等待线程完成
t.detach() // 分离线程,让它在后台运行
示例代码一
#include <iostream>
#include <thread>
void print_message() { std::cout << "Hello, world!" << std::endl;
}
int main() { std::thread t(print_message);t.join(); return 0;
}
示例代码二
#include <iostream>
#include <thread>
#include <functional> // 包含 std::ref
using namespace std;void increment(int& x) {x++; // 对参数进行递增操作
}int main() {int num = 5;thread t(std::ref(increment), std::ref(num)); // 可用方式一// thread t(increment, std::ref(num)); // 可用方式二// thread t(increment, num); 这个会报错!!!t.join();cout << "After increment: " << num << endl;cout << "increment: " << increment << endl;return 0;
}
二、 C++11 Thead易错
易错一:多线程使用了局部变量
1、有些运行环境下会出现Aborted (core dumped),原因是a是局部变量,在test作用域内会消失,而在线程内继续引用了a;
2、有些运行环境是不会报错,但是会出现结果不可预测
hq@nuc:~/java/my-project2$ ./a.out
32766
示例代码
#include <iostream>
#include <thread>
std::thread t;
// int a = 1; // 正确示例应该将a变成全局区域
void foo(int& x) {std::this_thread::sleep_for(std::chrono::seconds(2));x += 1;std::cout << x << std::endl;
}void test(){int a = 1;t = std::thread(foo, std::ref(a));
}int main() {test();t.join();return 0;
}return 0;
}
易错二:多线程使用了局部变量
1、有些运行环境下会出现Aborted (core dumped),原因是a是局部变量,在test作用域内会消失,而在线程内继续引用了a;
2、有些运行环境是不会报错,但是会出现结果不可预测
(py37) hq@nuc:~/java/my-project2$ ./a.out
0
1
示例代码二:
#include <iostream>
#include <thread>
std::thread t;
void foo(int* x) {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << *x << std::endl;*x += 1;std::cout << *x << std::endl;
}int main() {int *a = new int(20);t = std::thread(foo, a);delete a;t.join();return 0;
}
正确示例
#include <iostream>
#include <thread>
// std::thread t;
void foo(int* x) {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << *x << std::endl;*x += 1;std::cout << *x << std::endl;
}int main() {std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);std::thread t([sharedPtr]() {foo(sharedPtr.get());});std::thread t(foo, sharedPtr.get());t.join();return 0;
}
线程池
#include <iostream> // 包含标准输入输出流的头文件。
#include <thread> // 包含线程相关的头文件。
#include <vector> // 包含向量容器的头文件。
#include <queue> // 包含队列容器的头文件。
#include <mutex> // 包含互斥量的头文件,用于实现线程安全。
#include <condition_variable> // 包含条件变量的头文件,用于实现线程同步。
#include <functional> // 包含函数对象的头文件,用于传递任务函数。
#include <glog/logging.h>class ThreadPool { // 定义了一个名为 ThreadPool 的类。
public:ThreadPool(size_t numThreads) : stop(false) { // 线程池的构造函数,接受一个参数 numThreads,表示线程池中的线程数量。初始化列表 stop(false) 初始化了成员变量 stop,将其设置为 false,表示线程池初始状态下不处于停止状态。for (size_t i = 0; i < numThreads; ++i) { // 使用循环创建指定数量的工作线程。workers.emplace_back( // 在工作线程向量中添加一个新的线程,使用 Lambda 表达式初始化线程的执行函数。[this] {while (true) { // 工作线程的主循环,保持线程池始终处于运行状态。std::function<void()> task; // 定义了一个函数对象 task,用于存储要执行的任务。{std::unique_lock<std::mutex> lock(queueMutex); // 创建一个互斥锁 lock,用于保护任务队列。condition.wait(lock, [this] { return stop || !tasks.empty(); }); // 等待条件变量,直到满足 stop 或者任务队列不为空的条件。if (stop && tasks.empty()) { return; } // 如果线程池被要求停止并且任务队列为空,则退出线程。task = std::move(tasks.front()); // 从任务队列中获取任务并移动到 task 中。tasks.pop(); // 从任务队列中移除任务。}task(); // 执行任务。}});}}template<class F>void enqueue(F&& f) { // 定义一个模板函数 enqueue,用于向任务队列中添加任务。{std::unique_lock<std::mutex> lock(queueMutex); // 创建一个互斥锁 lock,用于保护任务队列。tasks.emplace(std::forward<F>(f)); // 将任务添加到任务队列中。}condition.notify_one(); // 通知一个等待中的线程有新任务可执行。}~ThreadPool() { // 线程池的析构函数,用于停止线程池并等待所有线程完成工作。{std::unique_lock<std::mutex> lock(queueMutex); // 创建一个互斥锁 lock,用于保护任务队列。stop = true; // 将停止标志设置为 true,表示线程池将要停止。}condition.notify_all(); // 通知所有等待中的线程停止。for (std::thread& worker : workers) { worker.join(); } // 等待所有工作线程完成工作并退出。}private:std::vector<std::thread> workers; // 存储工作线程的向量。std::queue<std::function<void()>> tasks; // 存储任务的队列,每个任务都是一个可调用的函数对象。std::mutex queueMutex; // 保护任务队列的互斥量。std::condition_variable condition; // 用于线程同步的条件变量。bool stop; // 表示线程池是否停止的标志。
};// 示例任务函数
void taskFunction(int taskId) {// std::cout << "Task " << taskId << " is running in thread " << std::this_thread::get_id() << std::endl;// std::cout << "Task " << taskId << std::endl;LOG(INFO) << "Task " << taskId << " is running in thread " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));
}int main() {ThreadPool pool(10); // 创建一个拥有4个线程的线程池// 将一些任务提交到线程池for (int i = 0; i < 1000; ++i) {pool.enqueue([i] { taskFunction(i); });}// 主线程等待所有任务完成std::this_thread::sleep_for(std::chrono::seconds(2)); // 等待足够的时间以确保所有任务完成return 0;
}
线程数组、任务数组
1、线程数组,是不能关闭的,只能是while(true)
2、线程数组,循环从任务数组中取任务
相关文章:
C++11 Thead线程和线程池
参考资料: 2、5.lock_guard 与 std::unique_lock-陈子青的编程学习课堂 (seestudy.cn) 3、C11 多线程编程-小白零基础到手撕线程池_哔哩哔哩_bilibili 一、 C11 Thead线程库的基本使用 # include <thread> std::thread t(function_name, args...); // 线…...

Windows版Apache 2.4.59解压直用(免安装-绿色-项目打包直接使用)
windows下Apache分类 Apache分为 安装版和解压版 安装版: 安装方便,下一步------下一步就OK了,但重装系统更换环境又要重新来一遍,会特别麻烦 解压版(推荐): 这种方式(项目打包特别方便&#x…...

刀具表面上的微结构
刀具表面微结构通常指在刀具表面对特定功能设计的微观纹理,这些纹理可以是沟槽、凹坑、凸起或任何其他形式的微观图案。这些微结构的设计和应用是为了改善刀具的切削性能,减少切削力和切削温度,提高切削效率和精度,同时降低切削液…...

css3实现微信扫码登陆动画
在做微信扫码登陆时,出现一个背景光图上下扫码动画,用css3图片实现。 实现原理: 1.准备一个渐变的背景.png图 2.css动画帧实现动画 看效果: css代码: #wx-scan{position: absolute;top:0px;left: 50%;z-index: 3;ma…...
vue3 导入excel数据
所需包 "xlsx": "^0.18.5"页面导入包 import * as XLSX from xlsx; import {genFileId, UploadProps, UploadRawFile,ElTable } from element-plus;页面 <el-upload accept".xlsx" :on-change"changeExcel" :on-exceed"ha…...
C# linq 根据多字段动态Group by
实现类: public static class LinqHepler {/// <summary>/// 根据单个字段动态Group/// </summary>/// <typeparam name"T"></typeparam>/// <param name"source"></param>/// <param name"prop…...

C语言学习/复习22----阶段测评编程题
一、阶段测评练习 题1: 题2:...

LeetCode-1766. 互质树【树 深度优先搜索 广度优先搜索 数组 数学 数论】
LeetCode-1766. 互质树【树 深度优先搜索 广度优先搜索 数组 数学 数论】 题目描述:解题思路一:DFS 中记录节点值的深度和编号,回溯写法。关键点是1 < nums[i] < 50解题思路二:0解题思路三:0 题目描述࿱…...
“数据安全服务能力”评定资格认证!不容错过
数据安全服务能力评定是指对数据安全服务提供商从事数据安全服务综合能力的评定,包括技术能力、服务能力、质量保证能力、人员构成与素质、经营业绩、资产状况等要素。 一、能力评定类型与等级 数据安全服务能力分为二个类型:数据安全评估、数据安全建…...
【MATLAB 分类算法教程】_3麻雀搜索算法优化支持向量机SVM分类 - 教程和对应MATLAB代码
分类代码案例3:麻雀搜索算法优化支持向量机SVM分类 - MATLAB完全代码教程 1. 初始化代码2.读取数据代码3.数据预处理代码4.利用麻雀搜索算法SSA求解最佳的SVM参数c和g代码5.根据最佳的参数进行SVM模型训练代码6.SVM模型预测代码7.准确率分析以及分类结果对比作图代码本文以红酒…...
利用机器学习库做动态定价策略的例子
动态定价是一个复杂的问题,涉及到市场需求、库存、竞争对手行为、季节性因素等多个变量。在实际应用中,动态定价通常需要复杂的模型和大量的数据分析。我选择使用Python(Golearn库)进行机器学习模型的训练和部署,而将G…...

Tcpdump -r 解析pcap文件
当我们使用命令抓包后,想在命令行直接读取筛选怎么办?-r参数就支持了这个 当你使用 tcpdump 的 -r 选项读取一个之前捕获的数据包文件,并想要筛选指定 IP 地址和端口的包时,你可以在命令中直接加入过滤表达式。这些过滤表达式可以…...

[dvwa] sql injection(Blind)
blind 0x01 low 1’ and length(version()) 6 # syntax: substr(string , from<start from 1>, cut length) 1’ and substr(version(),1,1) ‘5’ # 1’ and substr(version(),2,1) ‘.’ # 1’ and substr(version(),3,1) ‘7’ # 1’ and substr(version(),4,…...

linux 挂载云盘 NT只能挂载2T,使用parted挂载超过2T云盘
一、删除原来挂载好的云盘和分区 1、查看挂载号的云盘 fdisk -l 发现我们有5千多G但是只挂载了2T,心里非常的慌张!十分的不爽! 好,我们把它干掉,重新分区! 2、解除挂载 umount /homeE 没保存跳转到&…...

用Skimage学习数字图像处理(021):图像特征提取之线检测(下)
本节是特征提取之线检测的下篇,讨论基于Hough变换的线检测方法。首先简要介绍Hough变换的基本原理,然后重点介绍Skimage中含有的基于Hough变换的直线和圆形检测到实现。 目录 10.4 Hough变换 10.4.1 原理 10.4.2 实现 10.4 Hough变换 Hough变换&…...
ArduPilot飞控之Gazebo + SITL + MP的Jetson Orin环境搭建
ArduPilot飞控之Gazebo SITL MP的Jetson Orin环境搭建 1. 源由2. Linux环境整理3. 安装Gazebo环境3.1 安装Gazebo3.2 安装插件3.3 配置插件3.4 测试Gazebo 4. 安装Arudpilot-SITL环境4.1 克隆工程4.2 编译准备4.3 环境配置4.4 配置编译4.5 测试运行 5. 测试运行6. 参考资料 1…...
前端错误监控的方法有哪些
前端错误监控是指通过各种手段收集、分析和处理前端应用运行中发生的错误 常用的前端错误监控的方法有 使用 try catch 方法 捕获特定代码块中的错误多用于处理特定函数或代码段可能抛出的异常,尤其是异步代码网络请求错误监控 promise.catchtry catch全局错误处理…...

✌粤嵌—2024/3/11—跳跃游戏
代码实现: 方法一:递归记忆化 int path; int used[10000];bool dfs(int *nums, int numsSize) {if (path numsSize - 1) {return true;}for (int i 1; i < nums[path]; i) {if (used[path i]) {continue;}path i;used[path] 1;if (dfs(nums, num…...

Docker入门实战教程
文章目录 Docker引擎的安装Docker比vm虚拟机快 Docker常用命令帮助启动类命令镜像命令docker imagesdocker searchdocker pulldocker system dfdocker rmi 容器命令redis前台交互式启动redis后台守护式启动Nginx容器运行ubuntu交互式运行tomcat交互式运行对外暴露访问端口 Dock…...

数据结构初阶:二叉树(一)
树概念及结构 树的概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 有一个特殊的结点&a…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...