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

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...