【C++】详解std::mutex
2023年9月11日,周一中午开始
2023年9月11日,周一晚上23:25写完
目录
- 概述
- 头文件
- std::mutex类的成员
- 类型
- 方法
- 没有std::mutex会产生什么问题
- 问题一:数据竞争
- 问题二:不一致
- lock和unlock
- 死锁
概述
std::mutex是C++标准库中提供的一种同步原语,用于保护共享资源的访问。
std::mutex通过锁定互斥锁来实现对共享资源的保护。当一个线程获取了互斥锁后,其他线程必须等待该互斥锁被释放才能继续访问共享资源。这样可以确保在同一时刻只有一个线程能够访问共享资源,从而避免了多个线程同时访问同一资源而导致的数据竞争和不一致问题。
头文件
#include<mutex>
std::mutex类的成员
类型
native_handle_type 原生的互斥锁句柄类型
方法
(constructor) 构造互斥锁(公共函数)
lock 锁上互斥锁(公共函数)
try_lock 如果互斥锁没锁上就锁上互斥锁(公共函数)
unlock 解除互斥锁(公共函数)
native_handle 获取原生的互斥锁句柄(公共函数)
没有std::mutex会产生什么问题
问题一:数据竞争
在这个程序中,共享资源是count,count的值为0
按理来说,一个线程给count增加100000,另一个线程给count减去100000,最后的count应该还是0,但是事实上却不是这样,这就是数据竞争所造成的。
#include <iostream>
#include <mutex>
#include <thread>int count = 0;void thread1() {for(int i = 0; i < 100000; i++) {count++; }
}void thread2() {for(int i = 0; i < 100000; i++) { count--;}
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();std::cout <<"count:"<< count << std::endl; // 可能打印非0值
}
问题二:不一致
多个线程对共享数据进行操作,由于缓存一致性问题,可能导致其中一个线程看到的数据不是最新值。
比如在这个程序里面,有时候判断x==1是true,有时候判断x==1是false
#include <iostream>
#include <mutex>
#include <thread>int x = 0;void thread1() {x = 1;
}void thread2() {if(x == 1)std::cout << "x is 1" << std::endl; elsestd::cout << "x is not 1" << std::endl;
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();}
lock和unlock
通过lock/unlock可以保证任何时刻只有一个线程在访问共享资源,从而避免数据竞争问题。
#include <iostream>
#include <mutex>
#include <thread>std::mutex mutex;
int count = 0;void thread1() {for(int i = 0; i < 100000; i++) {// 锁定互斥锁mutex.lock(); count++; // 解锁互斥锁mutex.unlock();}
}void thread2() {for(int i = 0; i < 100000; i++) { // 锁定互斥锁mutex.lock(); count--;// 解锁互斥锁mutex.unlock();}
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();std::cout <<"count:"<< count << std::endl;
}
可以看到数据竞争的问题得到了解决
死锁
死锁(Deadlock)是多线程或多进程编程中的一个严重问题,它会导致程序无法继续执行下去,因为一组线程或进程相互等待对方释放资源,但永远无法满足条件,从而陷入僵局。
死锁的定义是:多个线程因为抢占和持有资源而造成的一种互相等待的僵局状态。
#include <iostream>
#include <thread>
#include <mutex>std::mutex mutex1;
std::mutex mutex2;void threadA() {std::cout << "Thread A: Attempting to lock mutex1..." << std::endl;mutex1.lock();std::this_thread::sleep_for(std::chrono::milliseconds(1));std::cout << "Thread A: Attempting to lock mutex2..." << std::endl;mutex2.lock();// 执行任务...mutex2.unlock();mutex1.unlock();
}void threadB() {std::cout << "Thread B: Attempting to lock mutex2..." << std::endl;mutex2.lock();std::this_thread::sleep_for(std::chrono::milliseconds(1));std::cout << "Thread B: Attempting to lock mutex1..." << std::endl;mutex1.lock();// 执行任务...mutex1.unlock();mutex2.unlock();
}int main() {std::thread t1(threadA);std::thread t2(threadB);t1.join();t2.join();return 0;
}
可以看到程序一直卡住
为什么会卡住呢?
-
线程A首先尝试锁定
mutex1
,并成功获得锁。 -
线程B首先尝试锁定
mutex2
,并成功获得锁。 -
接下来,线程A想要锁定
mutex2
,但它被线程B持有,因此线程A被阻塞,无法继续执行,等待mutex2
被释放。 -
同样地,线程B想要锁定
mutex1
,但它被线程A持有,因此线程B也被阻塞,等待mutex1
被释放。
现在,线程A和线程B都被阻塞,它们相互等待对方释放资源,但又不会主动释放自己的锁。这就是典型的死锁情况:两个或多个线程互相等待对方释放资源,导致程序无法继续执行下去。
根本原因在于线程拿不到锁时就会被阻塞。
相关文章:
【C++】详解std::mutex
2023年9月11日,周一中午开始 2023年9月11日,周一晚上23:25写完 目录 概述头文件std::mutex类的成员类型方法没有std::mutex会产生什么问题问题一:数据竞争问题二:不一致lock和unlock死锁 概述 std::mutex是C标准库中…...
Matlab图像处理-Lab模型
Lab模型 Lab模型是由CIE(国际照明委员会)制定的一种彩色模型。该模型与设备无关,弥补了RGB模型和CMYK模型必须依赖于设备颜色特性的不足; 另外,自然界中的任何颜色都可以在Lab空间中表现出来,也就是说RGB和…...
分布式ETL工具Sqoop实践
Mysql数据准备 1、在node02节点登录Mysql。 mysql -uroot -proot2、新建数据库testdb。 create database testdb;3、新建数据表ts。 use testdb; create table ts(id int, name varchar(10), age int, sex char(1));4、向表中插入数据。 insert into ts values(10001,张三…...
展会预告 | 图扑邀您共聚 IOTE 国际物联网展·深圳站
参展时间:9 月 20 日- 22 日 图扑展位:9 号馆 9B 35-1 参展地址:深圳国际会展中心(宝安新馆) IOTE 2023 第二十届国际物联网展深圳站,将于 9 月 20 日- 22 日在深圳国际会展中心(宝安…...
如何下载安装 WampServer 并结合 cpolar 内网穿透,轻松实现对本地服务的公网访问
文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境,是一组常用来…...
iOS添加Mapbox地图库
配置凭据 注册并导航到Account页面。你将需要: 公共访问令牌: 从帐户的tokens页面,你可以复制默认的公共令牌或单击"create a token"按钮来创建新的公共令牌。 带有Downloads:Read范围的秘密访问令牌: 从你帐户的t…...
destoon根据目录下的html文件生成地图索引
因为项目需要,destoon根据目录下的html文件生成地图索引,操作方法,代码如下: <?php $new_array array(); function loopDir($dir,&$new_array,$modurl) {$handle opendir($dir);header("Content-Type:text/xml&qu…...
gRPC之gRPC流
1、gRPC流 从其名称可以理解,流就是持续不断的传输。有一些业务场景请求或者响应的数据量比较大,不适合使用普通的 RPC 调用通过一次请求-响应处理,一方面是考虑数据量大对请求响应时间的影响,另一方面业务场景的设计不一 定需…...
Kafka Shell命令交互
Kafka提供了一个命令行工具,用于管理和与Kafka集群交互。这个命令行工具通常称为Kafka Shell,它允许您执行各种操作,如创建主题、发送和消费消息、查看主题列表等。 以下是一些常用的Kafka Shell命令: 创建主题(Topic): kafka-topics.sh --create --topic my-topic --pa…...
什么是回归测试?
什么是回归测试? 回归测试被定义为一种软件测试类型,以确认最近的程序或代码更改未对现有功能产生不利影响。 回归测试只不过是全部或部分选择已执行的测试用例,然后重新执行以确保现有功能正常运行。 进行此测试是为了确保新代码更改不会…...
ZTMap是如何在相关政策引导下让建筑更加智慧化的?
近几年随着智慧楼宇概念的深入,尤其是在“十四五规划”“新基建”“数字经济”等相关战略和政策的引导下,智慧楼宇也迎来了快速发展期,对推动智慧城市系统的建设越来越重要。那么究竟什么是智慧楼宇呢?智慧楼宇其实就是整合楼宇内…...
Python:函数和代码复用
嗨喽,大家好呀~这里是爱看美女的茜茜呐 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了,直接在文末名片自取就可 1、关于递归函…...
three.js——模型对象的使用材质和方法
模型对象的使用材质和方法 前言效果图1、旋转、缩放、平移,居中的使用1.1 旋转rotation(.rotateX()、.rotateY()、.rotateZ())1.2缩放.scale()1.3平移.translate()1.4居中.center() 2、材质属性.wireframe 前言 BufferGeometry通过.scale()、…...
sql explain
目录 1. sql explain每个字段对应的含义1.1. id1.2. select_type1.3. table1.4. partitions1.5. type1.6. possible_keys1.7. key1.8. key_len1.9. ref1.10. rows1.11. Extra 索引实践联合索引最左列原则全值匹配不建议在索引列上做任何操作, 否则索引会失效转而全表扫描尽量使…...
【LeetCode-简单题】剑指 Offer 05. 替换空格
文章目录 题目方法一:常规做法:方法二:双指针做法 题目 方法一:常规做法: class Solution {public String replaceSpace(String s) {int len s.length() ;StringBuffer str new StringBuffer();for(int i 0 ; i &l…...
数字虚拟人制作简明指南
如何在线创建虚拟人? 虚拟人,也称为数字化身、虚拟助理或虚拟代理,是一种可以通过各种在线平台与用户进行逼真交互的人工智能人。 在线创建虚拟人变得越来越流行,因为它为个人和企业带来了许多好处。 推荐:用 NSDT编辑…...
Nginx 文件解析漏洞复现
一、漏洞说明 Nginx文件解析漏洞算是一个比较经典的漏洞,接下来我们就通过如下步骤进行漏洞复现,以及进行漏洞的修复。 版本条件:IIS 7.0/IIS 7.5/ Nginx <8.03 二、搭建环境 cd /vulhub/nginx/nginx_parsing_vulnerability docker-compos…...
Lombok依赖
一.介绍 Project Lombok 是一个 Java 库,它会自动插入编辑器和构建工具,为您的 Java 增添趣味。永远不要再写另一个 getter 或 equals 方法,使用一个注释,您的类有一个功能齐全的构建器,自动化您的日志记录变量等等。…...
XML 和 JSON 学习笔记(基础)
XML Why XML 的出现背景:在实际开发中,不同语言(如Java、JavaScript等)的应用程序之间数据传递的格式不同,导致它们进行数据交换时很困难,XML就应运而生了!(XML 是一种通用的数据交…...
L1-005 考试座位号分数 15
每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试…...
无涯教程-JavaScript - CEILING.MATH函数
描述 CEILING.MATH函数将数字四舍五入到最接近的整数或最接近的有效倍数。 Excel CEILING.MATH函数是Excel中的十五个舍入函数之一。 语法 CEILING.MATH (number, [significance], [mode])争论 Argument描述Required/OptionalNumberNumber must be less than 9.99E307 and …...
ChatGPT提示词(prompt)资源汇总
文章目录 awesome-chatgpt-promptsLearn PromptingSnack PromptFlow GPTPrompt VineChatGPT 指令大全AI Toolbox HubAI Short ChatGPT是一种强大的生成式AI模型,而提示词(prompt)则是与ChatGPT一起使用的指导性文本,用于引导模型生…...
MySQL 几种导数据的方法与遇到的问题
零、说在前面 MySQL导数据通常使用第三方工具和MySQL自身的工具,本文分别就这两类方法分别介绍。 一、第三方工具之 Navicat 1.1、Navicat的“数据传输”工具 打开Navicat,点击“工具”标签,找到“数据传输”,即可看到操作界面。…...
(21)多线程实例应用:双色球(6红+1蓝)
一、需求 1.双色球: 投注号码由6个红色球号码和1个蓝色球号码组成。 2.红色球号码从01--33中选择,红色球不能重复。 3.蓝色球号码从01--16中选择。 4.最终结果7个号码:61;即33选6(红) 16选1(蓝) 5.产品: …...
升级OpenSSL并进行编译安装
Packaging (OpenSSL)组件存在安全漏洞的原因是由于当前爆出的Openssl漏洞。 这个漏洞可能会导致泄露隐私信息,并且涉及的机器和环境也有所不同,因此修复方案也会有所不同。 目前,一些服务器使用的Nginx是静态编译OpenSSL,直接将Op…...
Spring整合RabbitMQ
一、步骤 生产者 ① 创建生产者工程 ② 添加依赖 ③ 配置整合 ④ 编写代码发送消息 消费者 ① 创建消费者工程 ② 添加依赖 ③ 配置整合 ④ 编写消息监听器 二、代码 生产者工程 1.在生产者工程和消费者工程中都导入如下依赖 <dependencies><dependency&g…...
MySQL——事务和视图
2023.9.17 本章开始介绍TCL语言(Transaction Control Language 事务控制语言)。 事务 事务的概念:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。 事务的特性:ÿ…...
做好制造项目管理的5个技巧
制造过程通常由不同的要素组成,如采购材料、与供应商合作、优化生产线效率等。制造商还需要处理库存、物流和分销。 为了确保制造项目在预算范围内按时完成,并且不遗漏任何环节,企业必须建立项目管理流程,以帮助改善组织流程和效…...
JavaScript中While循环
JavaScript中处理For循环,还有一种循环while循环; ● 例如我们之前写了一个模拟举重次数的For循环,如下所示 for (let rep 1; rep < 10; rep) {console.log(举重${rep}次); }● 我们也可以使用while循环去实现这种功能 let rep 1; whi…...
python经典百题之乒乓球比赛
题目: 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。第一种方式: 思路…...
wordpress 模板破解版/正规百度推广
随着技术大幅进步,可再生能源击败化石燃料的几率日益增大,可再生能源电源与电网公司并网的必要性在迅速降低。 沃伦 巴菲特(Warren Buffett)与伊龙 马斯克(Elon Musk)正在进行一场对决,这场对决涉及到是否需要、何时进行以及如何过渡到电力行…...
亚马逊国际站官网/北京营销推广网站建设
目录 一、总结 一句话总结:a、单元测试的测试代码在test文件夹下,和源码不在同一个文件夹下1、JUnit中什么时候使用assertTrue,assertFalse语句?2、单元测试是什么?二、java使用Junit测试实例 junit是什么?…...
汕头公司做网站/图片搜索图片识别
返回:贺老师课程教学链接 项目要求 【项目:分段函数求值switch语句版】从键盘输入x的值(要求为整型),根据公式1计算并输出x和y的值。要求用switch语句完成。[参考解答] 解法1:各分段的标准都为2的倍数&…...
宁德北京网站建设/网络域名
启动步骤: 1.启动3台虚拟机【都用root登录】 2.启动hadoop: start-all.sh,然后jps进行测试出现633 第一台 6 第二台3 第三台 3 讲真我刚开始就不知道 633什么意思。说的不明不白的。 3.启动3台zookeeper: zkServer.sh start…...
镇江网站建设优化案例分析/seo sem是啥
xml基础知识 标记语言<> XML与HTML区别 1.HTML主要用来显示 XML是用来进行数据传输 2.HTML是一种预定义的(<a>表示超链接),xml不是预定义的(<a>就不是超链接) XML主要作用:存储和传输复杂的关系模型数据&#…...