Modern C++ std::mutex底层原理

前言

我时常有这样的疑问:

  1. std::mutex怎么就能保证后面的语句100%安全哪?
  2. CPU reordering就不会把这些语句重排到mutex前面执行?
  3. 而且各个CPU都是有L1、L2缓存的,如果mutex后面要访问的的变量在这些缓存中怎么办?

带着这些疑问我们先看看std::mutex是怎么实现的。

std::mutex::lock流程图

先给个图,再细说。

底层原理

先写个简单的cpp程序:

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::lock_guard, std::adopt_lock

std::mutex mtx;           // mutex for critical section
int total=0;

void print_thread_id(int id) {
        mtx.lock();
        for(int i=0;i<10000;i++) total++;
        mtx.unlock();
}

int main()
{
        print_thread_id(1);
        print_thread_id(2);
        std::cout<<"total="<<total<<std::endl;
        return 0;
}

我没起线程啊,只想看看std::mutex是怎么lock的, 这里调用print_thread_id两次也是故意的,因为第一次很多函数符号都没解决(函数@plt),遇到一个函数都要到ld里走一圈,很烦人。而第二次调用就用不着了。

在第二个print_thread_id上加断点,gdb中layout asm看汇编(也可以直接看glibc源码,实际源码有太多宏更不如汇编看的直接):

一路si(单步instruction执行),来到了关键指令:lock cmpxchg

 $r8正好执行我们定义的全局变量mtx, 从上个截图可以看到mtx结构中第一个member是int类型的__lock(看到名字也能盲猜这是mutex::lock的关键),而edi=1。

cmpxchg指令语法如下(请把cmos_lock看成mtx.__lock,  %edx为1):

 cmpxchg会原子的完成下面的IF+赋值,不会让别的线程看到中间状态。

 没被锁的情况下,destination(mtx.__lock)为0,accumulator($EAX)为0(pthread_mutex_lock+91 xor %eax,%eax使得eax的值为0),故ZF标志位被置为1,同时把source(1,pthread_mutex_lock+86 mov 1,%edi)存入mtx.__lock(表示锁上了)。

被别人锁的情况,请看下面的调试:

至于mtx.__lock会不会被各个CPU缓存,或者此指令后面的指令会不会被CPU重排,查了一些资料,也没弄100%明白,姑且先认为是吧。不然这么底层的东西早就造成大量问题了。

附上一些讨论:

concurrency - Is x86 CMPXCHG atomic, if so why does it need LOCK? - Stack Overflowicon-default.png?t=N7T8https://stackoverflow.com/questions/27837731/is-x86-cmpxchg-atomic-if-so-why-does-it-need-lock

multithreading - Do locked instructions provide a barrier between weakly-ordered accesses? - Stack Overflowicon-default.png?t=N7T8https://stackoverflow.com/questions/50280857/do-locked-instructions-provide-a-barrier-between-weakly-ordered-accesses
https://heather.cs.ucdavis.edu/matloff/public_html/50/PLN/lock.pdficon-default.png?t=N7T8https://heather.cs.ucdavis.edu/matloff/public_html/50/PLN/lock.pdf

 如果此处发现mtx.__lock已经是1,也就是别人锁上了,则转系统调用202号(sys_futex)挂起当前线程。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开启鸿蒙开发探索之旅ArkTS基本语法介绍(3)

上一章简单的介绍了鸿蒙HUAWEI DevEco Studio框架的搭建&#xff0c;这一章讲一下鸿蒙的主要开发一眼ArkTS的基本语法结构 1.ArkTS语法解释 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&…

信道编码理论【信息论安全】

目录 一. 信道编码模型 二. 信道编码速率与错误译码率 2.1 信道编码速率 2.2 平均错误率 三. 信道容量 四. 小结 一. 信道编码模型 &#xff08;1&#xff09;消息 假定消息集合为M&#xff0c;如下&#xff1a; &#xff08;2&#xff09;编码 将消息m映射成码字&…

怎么在PDF添加文本框?6种快速向PDF添加文字教程

有时您可能希望填写表格或在 PDF 文件中留下评论。这需要您将文本框和文本添加到 PDF。文本框是一个文本字段&#xff0c;您可以在其中键入文本。但是&#xff0c;除非您使用专用的 PDF 编辑器&#xff0c;否则编辑 PDF 文件具有挑战性。了解正确的 PDF 工具和将文本框添加到 P…

松木和桉木建筑模板:它们的性能和用途有何区别?

在建筑行业中&#xff0c;选择合适的模板材料对于保证施工质量和效率至关重要。松木和桉木是两种常用的建筑模板材料&#xff0c;它们各有特点和优势。特别是桉木&#xff0c;在某些方面相比松木有显著的优势。 松木建筑模板的特点 松木因其广泛的可用性和经济性而被广泛应用…

软件工程各种图

参考视频&#xff1a; 6 分钟学会 UML 类图_哔哩哔哩_bilibili 5 分钟学会 UML 时序图&#xff08;顺序图、序列图&#xff09;_哔哩哔哩_bilibili 3 分钟学会 UML 活动图_哔哩哔哩_bilibili 6 分钟学会 UML 用例图_哔哩哔哩_bilibili 是真的讲的非常好&#xff01;&#…

高保真度与流畅度MagicVideo-V2视频生成模型;3D人形虚拟角色;微调量化的扩散模型;自动给视频配音;非自回归音频生成

本文首发于公众号&#xff1a;机器感知 高保真度与流畅度MagicVideo-V2视频生成模型&#xff1b;3D人形虚拟角色&#xff1b;微调量化的扩散模型&#xff1b;自动给视频配音&#xff1b;非自回归音频生成 MagicVideo-V2: Multi-Stage High-Aesthetic Video Generation 本文提…

找不到msvcr120.dll怎样修复,分享4种修复方法

msvcr120.dll是Microsoft Visual C 2012 Redistributable Package的一个关键组件&#xff0c;负责提供C运行时库。许多应用程序在运行时都需要依赖这个库文件。然而&#xff0c;在日常使用过程中&#xff0c;不少用户会遇到msvcr120.dll丢失的问题&#xff0c;导致程序无法正常…

【PaperReading】3. PTP

Category Content 论文题目 Position-guided Text Prompt for Vision-Language Pre-training Code: ptp 作者 Alex Jinpeng Wang (Sea AI Lab), Pan Zhou (Sea AI Lab), Mike Zheng Shou (Show Lab, National University of Singapore), Shuicheng Yan (Sea AI Lab) 另一篇…

SpringBoot中使用SpringRetry实现重试机制(重试调用第三方API)

场景 SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)&#xff1a; SpringbootFastJson实现解析第三方http接口json数据为实体类(时间格式化转换、字段包含中文)_fastjson 发送http请求 接收实体,出现日期转换异常-CSDN博客 在调用…

中国社科院与新加坡社科大联合培养博士——快节奏,慢城市

现在都市生活都很快&#xff0c;小城市虽然节奏慢&#xff0c;但是相对来说&#xff0c;很多人反而愿意选择去快节奏的大城市&#xff0c;首先就是很现实的问题&#xff0c;薪资待遇&#xff0c;其次就是大城市缴纳的社会保险等到退休那一天会比在小城市多一点&#xff0c;为什…

postman使用-06断言

文章目录 一、断言定义二、 常用的断言三、断言-状态码&#xff08;1&#xff09;单一状态码断言&#xff1a;Status code:Code is 200 检查返回的状态码是否为200原始模板&#xff1a;修改后&#xff1a;括号里的200也可以改成自己要断言的状态码具体步骤&#xff1a;断言成功…

制造业CRM是什么?都有哪些特色功能?

近些年&#xff0c;制造业和别的行业一样&#xff0c;经历过翻天覆地的转型。从以分销为基础到客户至上&#xff0c;所有行业都在确定商业模式的全局性变化。在这样的环境下&#xff0c;不管什么规模的设备制造企业都意识到将创新与技术融进业务流程的必要性。CRM管理系统是促进…

Windows安装Rust环境(详细教程)

一、 安装mingw64(C语言环境) Rust默认使用的C语言依赖Visual Studio&#xff0c;但该工具占用空间大安装也较为麻烦&#xff0c;可以选用轻便的mingw64包。 1.1 安装地址 (1) 下载地址1-GitHub&#xff1a;Releases niXman/mingw-builds-binaries GitHub (2) 下载地址2-W…

C++力扣题目257--二叉树的所有路径

给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","1->3"]示例 …

如何进行大数据系统测试

大数据系统常见的架构形式有如下几种&#xff1a; Hadoop架构&#xff1a; Hadoop Distributed File System (HDFS)&#xff1a;这是一种分布式文件系统&#xff0c;设计用于存储海量数据并允许跨多台机器进行高效访问。 MapReduce&#xff1a;作为Hadoop的核心计算框架&#…

1.5 Unity中的数据存储 PlayerPrefs

Unity中的三种数据存储&#xff1a;数据存储也称为数据持久化 一、PlayerPrefs PlayerPrefs是Unity引擎自身提供的一个用于本地持久化保存与读取的类&#xff0c;以键值对的形式将数据保存在文件中&#xff0c;然后程序可以根据关键字提取数值。 PlayerPrefs类支持3种数据类…

php中常用的几个安全函数

1. mysql_real_escape_string() 这个函数对于在PHP中防止SQL注入攻击很有帮助&#xff0c;它对特殊的字符&#xff0c;像单引号和双引号&#xff0c;加上了“反斜杠”&#xff0c;确保用户的输入在用它去查询以前已经是安全的了。但你要注意你是在连接着数据库的情况下使用这个…

UG装配-动态干涉检查

如果设计的产品有运动部件&#xff0c;除了做静态干涉检查外&#xff0c;通常还要做动态干涉检查 动态检查可以使用如下命令&#xff1a;移动组件&#xff0c;序列 在动态干涉检查前&#xff0c;先装配好组件&#xff0c;并且是可运动状态 在使用移动组件命令对运动部件进行…

DePIN:重塑物理资源网络的未来

点击查看TechubNews更多相关推荐 一、DePIN&#xff1a;物理资源的新整合方式 Depin赛道的项目如雨后春笋般涌现&#xff0c;为市场注入了新的活力。作为先行者&#xff0c;Coinmanlabs已经深入布局Depin赛道&#xff0c;其中最引人注目的项目当属Grass。 什么是DePIN DePIN…

Flashduty 案例分享 - 途游游戏

Flashduty 作为功能完备的事件OnCall中心&#xff0c;可以接入云上、云下不同监控系统&#xff0c;统一做告警降噪分派、认领升级、排班协同&#xff0c;已经得到众多先进企业的认可。我们采访了一些典型客户代表&#xff0c;了解他们的痛点、选型考虑和未来展望&#xff0c;集…