C++ —— 线程同步(互斥锁)

C++ —— 线程同步(互斥锁)

  • 线程同步
  • 互斥锁(互斥量)
    • 测试代码
    • mutex互斥锁

线程同步

线程同步:多线程协同工作,协商如何使用共享资源。
C++11线程同步包含三部分内容:

  1. 互斥锁(互斥量)
  2. 条件变量
  3. 生产/消费者模型

互斥锁(互斥量)

只有加锁解锁两种状态,确保同一时间只有一个线程访问共享资源。
访问共享资源之前加锁,加锁成功访问资源,访问完成解锁释放。
若某线程持有锁,其他线程形成等待队列

C++11提供了4种互斥锁:

  • mutex:互斥锁(最常用)
  • timed_mutex:带超时机制的互斥锁
  • recursive_mutex:递归互斥锁
  • recursive_timed_mutex:带超时机制的递归互斥锁

测试代码

#include <iostream>
#include <thread>
using namespace std;void func (int n, const string& s) {for (int i = 1; i <= 10; i++) {cout << "No." << i << ", n = " << n << ", s = " << s << endl;this_thread::sleep_for(chrono::seconds(1));}
}
a
int main () {thread t1(func, 1, "t1");thread t2(func, 2, "t2");thread t3(func, 3, "t3");thread t4(func, 4, "t4");thread t5(func, 5, "t5");thread t6(func, 6, "t6");t1.join();t2.join();t3.join();t4.join();t5.join();t6.join();return 0;
}

cout属于全局对象,若多线程都用它向屏幕输出文字,会出乱子。线程越多,越容易乱。

mutex互斥锁

使用互斥锁cout加锁,代码如下:

#include <iostream>
#include <thread>
#include <mutex> // 使用互斥锁需要包含的头文件
using namespace std;mutex mtx; // 创建互斥锁对象,用于保护共享资源cout对象。void func (int n, const string& s) {for (int i = 1; i <= 10; i++) {// 每次调用cout对象之前,申请加锁mtx.lock();cout << "No." << i << ", n = " << n << ", s = " << s << endl;// 用完了就解锁mtx.unlock();this_thread::sleep_for(chrono::seconds(1));}
}int main () {// 代码不变...
}

再看一段示例代码:

#include <iostream>
#include <chrono> // 时间相关操作的头文件
#include <thread> // 线程相关操作的头文件
#include <mutex> // 互斥锁的头文件
using namespace std;int a = 0;
mutex mtx; // 创建互斥锁对象,用于保护共享资源a变量。void func () {for (int i = 0; i < 1000000; ++i) {mtx.lock();a++;mtx.unlock();}
}int main () {auto start = chrono::steady_clock::now();thread t1(func);thread t2(func);t1.join();t2.join();auto end = chrono::steady_clock::now();cout << "time = " << chrono::duration_cast<chrono::milliseconds>(end - start).count() << "ms" << endl;cout << "a = " << a << endl;return 0;
}

运行结果:

time = 101ms
a = 2000000

在代码中添加一些打印信息,能更清楚的观察到:两个线程申请加锁,只有一个成功,另外一个线程等待,直到第一个线程解锁后第二个线程才能加锁。

#include <iostream>
#include <chrono> // 时间相关操作的头文件
#include <thread> // 线程相关操作的头文件
#include <mutex> // 互斥锁的头文件
using namespace std;int a = 0;
mutex mtx;void func () {for (int i = 0; i < 1000000; ++i) {cout << "thread id: " << this_thread::get_id() << ", 申请加锁" << endl;mtx.lock();cout << "thread id: " << this_thread::get_id() << ", 加锁成功" << endl;a++;this_thread::sleep_for(chrono::seconds(5));mtx.unlock();cout << "thread id: " << this_thread::get_id() << ", 解锁" << endl;this_thread::sleep_for(chrono::seconds(1));}
}int main () {thread t1(func);thread t2(func);t1.join();t2.join();cout << "a = " << a << endl;return 0;
}

运行结果:

thread id: 139727756003072, 申请加锁
thread id: 139727756003072, 加锁成功
thread id: 139727747610368, 申请加锁
thread id: 139727756003072, 解锁
thread id: 139727747610368, 加锁成功
thread id: 139727756003072, 申请加锁
thread id: 139727747610368, 解锁

感谢浏览

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UI设计中的加载动画:优化用户体验的细节

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字产品泛滥的今天&#xff0c;用户对体验的要求早已超越功能本身。一个看似简单的加载动画&…

SpringBoot3+Vue3实战(Vue3快速开发登录注册页面并对接后端接口)(4)

目录 一、SpringBoot3Vue3实现基本增删改查。前后端通信交互、配置后端跨域请求。数据批量删除。(博客链接) 二、SpringBoot3Vue3快速开发登录、注册页面并实现对接。 &#xff08;1&#xff09;操作数据表employee(员工信息表)。 <1>修改employee表的字段组成。 <2&g…

Python标准库中bisect模块的bisect_right()函数在网格交易中的应用

本文将深入探讨Python标准库中bisect模块的bisect_right()函数在网格交易中的具体应用。 bisect模块 bisect模块是Python标准库中的一个模块&#xff0c;提供了对有序列表的插入和搜索操作的支持。它基于二分查找算法&#xff0c;可以高效地在有序列表中查找或插入元素&#x…

Excel(函数篇):IF函数、FREQUNCY函数、截取函数、文本处理函数、日期函数、常用函数详解

目录 IF函数等于判断区间判断与AND函数、OR函数一同使用IFNA函数和IFERROR函数 FREQUNCY函数、分断统计LEFT、RIGHT、MID截取函数FIND函数、LEN函数SUBSTITUTE函数ASC函数、WIDECHAR函数实战&#xff1a;如何获取到表中所有工作簿名称文本处理函数TEXT函数TEXTJOIN函数 日期函数…

生成PDF文件:从html2canvas和jsPdf渲染到Puppeteer矢量图

刚刚实现而已&#xff1a;第一次明白&#xff0c;双击或file:///打开html文件&#xff0c;居然和从localhost:3000打开同一个html文件有本质的区别。 字体居然还能以Base64代码嵌入到网页&#xff0c;只是太大太笨。 需要安装node.js&#xff0c;npm安装更多依赖&#xff1a;…

Git 分支删除操作指南(含本地与远程)

&#x1f680; Git 分支删除操作指南&#xff08;含本地与远程&#xff09; 在多人协作的开发过程中&#xff0c;定期清理已合并的临时分支&#xff08;如 feature/*、bugfix/*、hotfix/* 等&#xff09;可以保持仓库整洁&#xff0c;避免混乱。 &#x1f4cc; 分支命名规范回…

Qt中打开windows的cmd窗口并显示

在windows上&#xff0c;用Qt的GUI程序打开另一个程序&#xff0c;使用QProcess即可&#xff0c;并且被打开的程序通常也会显示出来&#xff0c;但是如果想要打开dos窗口并显示&#xff0c;并执行其中的命令或者批处理&#xff0c;则需要使用QProcess提供的windows特有的函数QP…

Modbus TCP到RTU:轻松转换指南!

Modbus TCP 到 RTU&#xff1a;轻松转换指南&#xff01; 在现代工业自动化领域&#xff0c;Modbus TCP和Modbus RTU两种通信协议因其高效、稳定的特点被广泛应用。然而&#xff0c;随着技术的发展和设备升级的需求&#xff0c;经常会遇到需要将这两种协议进行互相转换的场景。…

微信小程序订阅消息发送消息,点击消息进入小程序页面

1、在小程序官网订阅消息选用或创建消息模板获取模板ID可多个 如图&#xff1a; 2、微信小程序前端页面发送请求订阅权限 请求模板id的权限可以是一个可以是多个&#xff0c;用户同意订阅&#xff0c;获取code传递给后端——后端拿到code生成唯一的openid用于发送订阅消息 注…

卷积神经网络 - 卷积层

卷积神经网络一般由卷积层、汇聚层和全连接层构成&#xff0c;本文我们来学习卷积层。 卷积层&#xff08;Convolutional Layer&#xff09;是卷积神经网络&#xff08;CNN&#xff09;的核心组件&#xff0c;专门用于处理具有网格结构的数据&#xff08;如图像、音频、时间序…

Vue3全局化配置(ConfigProvider)

效果如下图&#xff1a; 在线预览 APIs ConfigProvider 参数说明类型默认值theme主题对象Theme{}abstractboolean是否不存在 DOM 包裹元素truetagstringConfigProvider 被渲染成的元素&#xff0c;abstract 为 true 时有效‘div’ Theme Type 名称说明类型默认值common?全…

LabVIEW烟气速度场实时监测

本项目针对燃煤电站烟气流速实时监测需求&#xff0c;探讨了静电传感器结构与速度场超分辨率重建方法&#xff0c;结合LabVIEW多板卡同步采集与实时处理技术&#xff0c;开发出一个高效的烟气速度场实时监测系统。该系统能够在高温、高尘的复杂工况下稳定运行&#xff0c;提供高…

若依excel工具类导出excel模板数据带下拉映射

导出模板代码&#xff0c;原理是combo属性 传递一个数组 里面是label下拉数组。 Overridepublic void downloadTemplate(HttpServletResponse response) {ExcelUtil<ThMachineryManageExcel> util new ExcelUtil<>(ThMachineryManageExcel.class);List<SysDist…

3.8 Spring Boot监控:Actuator+Prometheus+Grafana可视化

在Spring Boot应用中&#xff0c;通过整合Actuator、Prometheus和Grafana可以构建完整的监控体系&#xff0c;实现指标采集、存储和可视化。以下是具体实现步骤&#xff1a; 一、Spring Boot Actuator 配置 作用&#xff1a;暴露应用健康指标、性能数据等监控端点。 1. 添加依…

启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——二叉树序列构造探秘——堆的奥义与实现诗篇

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、堆的定义与结构二、堆的实现1.堆的初始化和销毁堆的初始化堆的销毁 2.向上调整算法和入堆向上调整算法入堆 3.向下调整算法和出堆顶数…

“Failed to Load SteamUI.dll” 错误详解:全面解析与高效解决方案,助你快速修复 Steam 客户端问题

在使用 Steam 客户端时&#xff0c;你是否遇到过 failed to load steamui.dll 错误&#xff1f;这个令人头疼的问题可能导致 Steam 无法正常启动&#xff0c;影响游戏体验。Failed to load steamui.dll 错误通常与文件损坏、系统配置或软件冲突有关&#xff0c;但无需担心&…

STM32 DAC详解:从原理到实战输出正弦波

目录 一、DAC基础原理1.1 DAC的作用与特性1.2 DAC功能框图解析 二、DAC配置步骤2.1 硬件配置2.2 初始化结构体详解 三、DAC数据输出与波形生成3.1 数据格式与电压计算3.2 正弦波生成实战3.2.1 生成正弦波数组3.2.2 配置DMA传输3.2.3 定时器触发配置 四、常见问题与优化建议4.1 …

CNN 稠密任务经典结构

FCN UNet FPN FCNUNETFPNpadding无&#xff08;逐渐变小&#xff09; 有&#xff08;左右对称&#xff09;上采样 双线性双线性 最近邻跳跃链接 相加 Cropcat 1x1卷积相加 三个网络差不多&#xff0c;UNet名字最直观&#xff0c;后续流传…

AI学习第二天--监督学习 半监督学习 无监督学习

目录 1. 监督学习&#xff08;Supervised Learning&#xff09; 比喻&#xff1a; 技术细节&#xff1a; 形象例子&#xff1a; 2. 无监督学习&#xff08;Unsupervised Learning&#xff09; 比喻&#xff1a; 技术细节&#xff1a; 形象例子&#xff1a; 3. 半监督学…

Elasticsearch:为推理端点配置分块设置

推理端点对一次可处理的文本量有限&#xff0c;具体取决于模型的输入容量。分块&#xff08;Chunking&#xff09; 是指将输入文本拆分成符合这些限制的小块的过程&#xff0c;在将文档摄取到 semantic_text 字段时会进行分块。分块不仅有助于保持输入文本在可处理范围内&#…