这个变量要不要用volatile修饰呢?

2d14f5477ec1723dcf94e0ce543a609b.jpeg

正文


大家好,又见面了,我是bug菌~

在嵌入式软件开发过程中,如果对volatile不熟,那可以你应该是个"假嵌入式程序员",因为一个变量需不需要使用volatile考虑的场景挺多的,如果在某些场景下乱用,会影响程序运行效率,有时候忘记加甚至会使得程序发生异常,那么bug菌今天就大家好好聊聊这个C语言关键字:

1

传统定义

volatile直译为“易变的”,也就是告诉编译器这个变量随时都可能发生变化,编译器你跟我“特殊照顾一下“。

那么编译器通常会怎么去处理使用volatile修饰的变量呢?

对于C变量都是代表着对应的内存,读取使用volatile修饰的变量,会直接从其所对应的内存地址中获取最新的数据,否则,编译器会对其访问进行优化,比如直接从缓存中读取副本、或者是从寄存器中读取副本。

这样就可能会导致数据更新不一致的问题。

2

最常用的地方

从前面对volatile的功能描述,我们可以知道volatile最常用于那些与硬件外设寄存器打交道的地址,这样确保每次对寄存器的读取都是从内存中获取的最新值,比如:

4e9ea24c36131276587dc0386f2d82f0.jpeg

再比如下图所示,如果我们向地址0x812100地址连续改变其值:

12a728ec2487a3f3f32cb1d25f27a626.jpeg

那么编译器通常会将其直接优化为第三条操作,并不会去执行前两条操作,这样会造成写寄存器时序上的问题。

如果采用volatile去修饰,则三条命令便会依次执行,达到我们代码所示三次操作的目的。

e539084ecee4a8486bb2dfcc1ffd572c.jpeg

3

更复杂一点的,也是最重要的 

其实对于volatile所解决的问题用更加专业的说法可以分为:可见性和有序性。

1、可见性

所谓可见性,通常是在多线程访问共享数据的情况,当一个线程对共享变量进行修改,而其他线程能否立即观察到这个修改的性质。

在我们目前大部分单核一级缓存的CPU无需考虑这个问题,而对于现场多核多级缓存处理器,各个现场都会维护着自己的缓存,如果仅仅只是更新到了自己的缓存中那么其他线程是无法立马感受到这个修改的,最终导致结果不一致。

2、有序性

很多时候也叫作重排序,说白了就是对执行指令进行了执行顺序上的优化,以不改变指令运行的最终结果,而改变指令的执行顺序。

编译器可以调整指令,同样处理器的多级流水线和乱序执行也同样可以改变指令执行顺序;甚至为了多级缓存的高效执行,也同样会对内存读写操作进行重排序。

然而这样的重排序,却会对多线程并发访问共享数据的过程中产生问题,从而不符合我们编程源码的预期执行顺序。

但对于volatile只能在一定程度上防止指令重排序,其只能保证单个变量访问的有序性,而不能保证整个程序的有序性,所以这一点是大家尤为要注意的。

所以讲了这么多,相信以后大家再开发中也都会遇到。

最后

      好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个~

bug菌唯一、永久、免费分享嵌入式技术知识平台~

876030fb4a2ee27e40abc29af9f0969d.jpeg

推荐专辑  点击蓝色字体即可跳转

☞  MCU进阶专辑 9dabfd9b6c2e30e9a4ba6944d4c28717.jpeg

☞  嵌入式C语言进阶专辑 30425c91c53b8e40c928281d7e85b10f.jpeg

☞  “bug说”专辑 a31d7ccd9516af5a4a77084a4f6fd9b4.jpeg

☞ 专辑|Linux应用程序编程大全

☞ 专辑|学点网络知识

☞ 专辑|手撕C语言

☞ 专辑|手撕C++语言

☞ 专辑|经验分享

☞ 专辑|电能控制技术

☞ 专辑 | 从单片机到Linux

309850b60fcd0c4e2e53f6cef79391b1.jpeg

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

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

相关文章

读像火箭科学家一样思考笔记12_实践与测试(下)

1. 舆论的火箭科学 1.1. 如果苹果违反了“即飞即测”原则,那苹果的iPhone就不会问世了 1.1.1. iPhone在其上市前的民意调查中相当失败 1.1.1.1. iPhone不可能获得太大市场份额,不可能。 1.1.1.1.1. 微软前CEO史蒂夫鲍尔默(Steve Ballmer&…

第15关 K8s HPA:自动水平伸缩Pod,实现弹性扩展和资源优化

------> 课程视频同步分享在今日头条和B站 大家好,我是博哥爱运维,这节课带来k8s的HPA 自动水平伸缩pod( 视频后面有彩蛋 : ) )。 我们知道,初始Pod的数量是可以设置的,同时业务也分流量高峰和低峰&a…

Deep Image Prior

深度图像先验 论文链接:https://sites.skoltech.ru/app/data/uploads/sites/25/2018/04/deep_image_prior.pdf 项目链接:https://github.com/DmitryUlyanov/deep-image-prior Abstract 深度卷积网络已经成为一种流行的图像生成和恢复工具。一般来说&a…

每日一练2023.11.28———N个数求和【PTA】

题目链接: L1-009 N个数求和 题目要求: 本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。 输入格式: 输入第一行给出一个正整…

三 STM32F4使用Sys_Tick 实现微秒定时器和延时

更多细节参考这篇 1. 什么是时钟以及作用 1.1 什么是时钟 时钟是由电路产生的周期性的脉冲信号,相当于单片机的心脏 1.2 时钟对于STM32的作用 指令同步:cpu和内核外设使用时钟信号来进行指令同步数据传输控制: 时钟信号控制数据在内部总…

【C数据(一)】数据类型和变量你真的理解了吗?来看看这篇

🌈write in front :🔍个人主页 : 啊森要自信的主页 ✏️真正相信奇迹的家伙,本身和奇迹一样了不起啊! 欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助&am…

Linux的Sysfs 接口

一、sysfs接口 在linux系统中,用户空间访问驱动程序一般是以“设备文件”的方式通过“read/write/ioctl”访问,还有一种方式,可以通过echo的方式来直接控制硬件或者修改驱动,也能为底层驱动提供一个接口便于应用层调用&#xff0c…

app上架一直显示审核中状态要怎么处理?

当你提交一个应用到App Store上时,它会经历一个审核过程。在这个过程中,苹果的审核人员会检查你的应用是否符合苹果的规定和标准。这个过程通常需要几天的时间,但是如果你的应用一直显示“审核中”状态,那么可能会有一些原因。 1…

广州华锐互动:VR虚拟现实内容创作工具带来全新的应用场景

随着科技的不断发展,低代码编辑工具已经成为了一种越来越受欢迎的开发方式。它可以帮助开发人员快速构建应用程序,降低开发成本,提高开发效率,而VR虚拟现实内容创作工具带来了全新的应用场景。 VR虚拟现实内容创作工具是广州华锐互…

AlphaFold的原理及解读

1、背景 蛋白质是生物体内一类重要的生物大分子,其结构复杂多样,蛋白质的结构对于理解其功能和参与的生物学过程具有重要意义。从生物学角度上看,蛋白质的结构可以分为四个层次:初级结构、二级结构、三级结构和四级结构。 初级结…

模拟实现offsetof宏(详解)

我们在以前学过这个offsetof函数,知道它的功能是求指针相较于起始位置的偏移量,我们今天要来写出一个宏,计算结构体中某成员变量相对于起始位置的偏移。 目录 1.offsetof函数 1.1offsetof函数介绍 1.2offsetof函数代码实现 2.offsetof函数…

python实现rpc的几种方式(SimpleXMLRPCServer 自带的、第三方ZeroRPC)、连接linux远程开发分布式锁、分布式id

1 python实现rpc的几种方式 1.1 SimpleXMLRPCServer 自带的 1.2 第三方ZeroRPC 2 连接linux远程开发 3 分布式锁 4 分布式id 1 python实现rpc的几种方式 # 远程过程调用-1 借助于rabbitmq,可以跨语言-2 SimpleXMLRPCServer 自带的-3 ZeroRPC-4 GRPC:跨语言的 htt…

dart多线程双向通信的案例----【小学4年级课程】

下面是运行后的打印顺序 I/flutter (20170): 上班 I/flutter (20170): 这里是校长室:main I/flutter (20170): 这里是饭堂:fantang1 I/flutter (20170): 这里是收发室--检查小孩发回去给他妈妈的信息是:我是秘书的儿子,我来到在校长室了。校长今晚想吃羊…

【Web】SWPUCTF 2022 新生赛 个人复现

目录 ①webdog1__start ②ez_rce ③ez_sql ④ez_1zpop ⑤file_maste ⑥Power! 挑了部分题,太简单的就没选进来(但选进来≠有难度) ①webdog1__start 进来没啥东西,右键查看源码 对于0e215962017,md5后也是以…

Salesforce原生ERP产品 vs. 集成:如何选择?

Salesforce允许企业管理所有的客户交互。随着Salesforce平台的日渐成熟,企业已经能够获取成倍的收益。会计解决方案和其他ERP工具尤其契合,客户数据不会碰壁,可以在服务交付和客户成功、发票和账单、收入确认和续订的过程中继续前进。 一些…

群晖NAS配置之自有服务器ngrok实现内网穿透

群晖NAS配置之自有服务器ngrok实现内网穿透 前言-内网穿透 内网穿透是指通过一种技术让外部网络可以访问到内网的NAS设备,这样即使在不同网络环境下,也能够远程访问和管理NAS设备。以下是一些常见的内网穿透方案: Synology官方提供的Quick…

IDEA 配置 gradle6.8.3 解决导入gradle项目下载太慢问题

由于平时用的是springboot 2.7 这里下载gradle-6.8.3 Gradle官网地址:https://services.gradle.org/distributions/ 1.下载gradle后,配置环境变量 GRADLE_HOME {gradle 文件路径} GRADLE_USER_HOME {jar下载路径,可以放maven jar保存路径…

链接2:静态链接、目标文件、符号和符号表

文章目录 静态链接符号解析 (symbolresolution)重定位 (relocation) 目标文件1.可重定位目标文件2.可执行目标文件3.共享目标文件 可重定位目标文件text:rodata:.data.bss.symtab.rel.text.rel.data:debug:line:strtab: 符号和符号表由m定义并能被其他模块引用的全局符号由其他…

基于Pix2Struct的文档信息提取【DocVQA】

文档信息提取涉及使用计算机算法从非结构化或半结构化文档(例如报告、电子邮件和网页)中提取结构化数据(例如员工姓名、地址、职务、电话号码等)。 提取的信息可用于各种目的,例如分析和分类。 DocVQA(文档…

MySQL基础进阶篇

进阶篇 存储引擎 MySQL体系结构: 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表而不是基于库的,所以存储引擎也可以被称为表引擎。 默认存储引擎是InnoDB。 相关操作: -- 查询建表语句 show create …