一篇文章带你了解C语言中volatile关键字
目录
- C语言中volatile关键字
- 总结
C语言中volatile关键字
volatile关键字是C语言中非常冷门的关键字,因为用到这个关键字的场景并不多。
当不用这个关键字的时候,CPU可能会对我们的代码做一定的优化:
内存中的数据要放入CPU中进行运算或控制,而这个数据的值是被放入寄存器中,然后再将寄存器中的数据进行运算或控制的,对于一个死循环int flag=1;while(flag);
来说;如果进行优化,则下次循环则不需要再次将flag内存中的值放入寄存器中,而是直接使用寄存器中已有的值进行循环;如果不进行优化,则下次还需要将flag内存中的值放入寄存器中,然后使用寄存器中的数据。
总结起来就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对其地址的稳定访问;如果不使用valatile,则编译器将对所声明的语句进行优化。
这两种情况在单线程的情况下区别不大,但是在多线程的情况下可能会有其他逻辑将flag修改为0,如果进行优化,则死循环不会停下来。
所以volatile的作用就是让变量不要被CPU优化,达到稳定访问内存的目的。
比如下面的代码:
我们在gcc下使用命令gcc test.c -O2 -g将代码进行优化,然后用命令objdump -S -d a.out > a.s将优化后的汇编代码放入a.s文件中,再用vim a.s查看a.s文件:
程序会一直在这一句代码中死循环:
加入volatile后:
再用相同的命令查看a.s文件:
可以看到每次循环都会读取pass的数据。
结论: volatile 忽略编译器的优化,保持内存可见性。
另外,const和volatile是不冲突的:
const volatile int a = 10;
const关键字要求变量a不能直接被写入,而volatile关键字要求每次读取数据的时候,都要从a所在的内存中读取,并不会改变变量a的值。
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!
相关推荐
-
C语言中volatile关键字的深入讲解
1. 什么是volatile关键字? volatile用于声明一个变量,告诉编译器该变量值容易发生改变,在编译.读取.存储该变量的时候都不要做任何优化,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取存储数据,不做优化,在我们做嵌入式开发的时候,该关键字作用很大,因为有时变量地址有可能是系统的一个外设地址,他的值的变化并不在程序控制范围内,随时有可能变化,因此需要对他进行声明,每次读取或者存储直接对地址进行操作,而不经过其他中间商,下面我以一个例子来分析vilatile
-
C语言中volatile关键字的作用与使用案例教程
一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问.另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度.以上是硬件级别的优化.再看软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化.编译器优化常用的方法有:将内存变量缓存到寄存器:调整指令顺序充分利用CPU指令流水线,常见的是重新排序读写指令.对常规内存进行优
-
探讨C语言中关键字volatile的含义
volatile 的意思是"易失的,易改变的".这个限定词的含义是向编译器指明变量的内容可能会由于其他程序的修改而变化.通常在程序中申明了一个变量时,编译器会尽量把它存放在通用寄存器中,例如ebx.当CPU把其值放到ebx中后就不会再关心对应内存中的值.若此时其他程序(例如内核程序或一个中断)修改了内存中它的值,ebx中的值并不会随之更新.为了解决这种情况就创建了volatile限定词,让代码在引用该变量时一定要从指定位置取得其值. 关键字volatile有什么含意?并给出三个不同的例
-
C语言 volatile与const同时使用应注意的问题
const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好不要做太激进的优化. "const"含义是"请做为常量使用",而并非"放心吧,那肯定是个常量"."volatile"的含义是"请不要做没谱的优化,这个值可能变掉的",而并非"你可以修改这个值"
-
一篇文章带你了解C语言中volatile关键字
目录 C语言中volatile关键字 总结 C语言中volatile关键字 volatile关键字是C语言中非常冷门的关键字,因为用到这个关键字的场景并不多. 当不用这个关键字的时候,CPU可能会对我们的代码做一定的优化: 内存中的数据要放入CPU中进行运算或控制,而这个数据的值是被放入寄存器中,然后再将寄存器中的数据进行运算或控制的,对于一个死循环int flag=1;while(flag);来说:如果进行优化,则下次循环则不需要再次将flag内存中的值放入寄存器中,而是直接使用寄存器中已有的
-
一篇文章带你弄清楚Redis的精髓
目录 一.Redis的特性 1.1 Redis为什么快? 1.2 Redis其他特性 1.3 Redis高可用 二.Redis数据类型以及使用场景 2.1 String 2.1.1 基本指令 2.1.2 应用场景 2.2 Hash 2.2.1 基本指令 2.2.2 应用场景 2.3 List 2.3.1 基本指令 2.3.2 应用场景 2.4 Set 2.4.1 基本指令 2.4.2 应用场景 2.5 ZSet(SortedSet) 2.5.1 基本指令 2.5.2 应用场景 三.Redis的事
-
一篇文章带你了解清楚Mysql 锁
一丶为什么数据库需要锁 数据库锁设计的初衷是处理并发问题.作为多用户共享 的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实 现这些访问规则的重要数据结构. 根据加锁的范围,MySQL 里面的锁大致可以分成全局锁.表级锁和行锁三类 二丶全局锁&全库逻辑备份 全局锁就是对整个数据库实例加锁.全局锁的典型使用场景是,做全库逻辑备份,全库逻辑备份有以下几种方式: 1.Flush tables with read lock (FTWRL) Flush tables with
-
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
一.搭建项目以及初始化配置 vue create ts_vue_btn 这里使用了vue CLI3自定义选择的服务,我选择了ts.stylus等工具.然后创建完项目之后,进入项目.使用快捷命令code .进入Vs code编辑器(如果没有code .,需要将编辑器的bin文件目录地址放到环境变量的path中).然后,我进入编辑器之后,进入设置工作区,随便设置一个参数,这里比如推荐设置字号,点下.这里是为了生成.vscode文件夹,里面有个json文件. 我们在开发项目的时候,项目文件夹内的文件很
-
一篇文章带你搞定SpringBoot中的热部署devtools方法
一.前期配置 创建项目时,需要加入 DevTools 依赖 二.测试使用 (1)建立 HelloController @RestController public class HelloController { @GetMapping("/hello") public String hello(){ return "hello devtools"; } } 对其进行修改:然后不用重新运行,重新构建即可:只加载变化的类 三.热部署的原理 Spring Boot 中热部
-
一篇文章带你搞定SpringBoot不重启项目实现修改静态资源
一.通过配置文件控制静态资源的热部署 在配置文件 application.properties 中添加: #表示从这个默认不触发重启的目录中除去static目录 spring.devtools.restart.exclude=classpath:/static/** 或者使用: #表示将static目录加入到修改资源会重启的目录中来 spring.devtools.restart.additional-paths=src/main/resource/static 此时对static 目录下的静态
-
一篇文章带你解决 IDEA 每次新建项目 maven home directory 总是改变的问题
Maven是基bai于项目对象模型,可以通du过一小段描述信息来管理zhi项目的构建,报告和文档的软件项dao目管理工具. 重装个系统,各种问题,idea 也出现各种问题 装了个新版的 idea 2020 2.x 版本的,不知道咋回事,其他都好使,就是创建 SpringBoot 项目时: 加载 pom.xml 总是出错,原因就是,新建立的项目 maven home directory 总是乱,没有安装 设置的默认方式 我试了,改当前项目的,不好使 该默认设置,不好使,网上的其他方法也试了,很奇怪
-
一篇文章带你使用SpringBoot基于WebSocket的在线群聊实现
一.添加依赖 加入前端需要用到的依赖: <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.webjars</groupId> <
随机推荐
- 理解Javascript_12_执行模型浅析
- C#中List〈string〉和string[]数组之间的相互转换
- Gson解析空字符串发生异常的处理方法
- IOS获取当前版本号 Bundle ID等信息的方法详解
- 时间戳与时间相互转换(php .net精确到毫秒)
- Android下拉刷新PtrFrameLayout的使用实例代码
- MySQL 5.7 学习心得之安全相关特性
- js对图片base64编码字符串进行解码并输出图像示例
- 给XML文档添加新 ”records”
- jquery uploadify如何取消已上传成功文件
- 广告放在文章页左上角的解决办法二
- jquery.qtip提示信息插件用法简单实例
- 同一个文件在windows和linux下计算md5哈希不一致的原因及解决方法
- 访问和更改关系数据,使用MSSQL外联接
- 详解Mysql自动备份与恢复的几种方法(图文教程)
- 必须会的SQL语句(一) 创建数据库与删除数据库
- IE浮动边界BUG延伸探讨
- Django模板继承 extend标签实例代码详解
- PHP后期静态绑定实例浅析
- python实现操作文件(文件夹)