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…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...