volatile bool flag;
volatile int a;

添加volatile限定符的变量会获得几个特性:

类型限定符volatile

强制内存读取

因为这个数据是“易变的(volatile)”,所以要时刻关注,不能偷懒

场景:

把内存中的变量拷贝到寄存器中进行处理以加快速度;

存在的问题:

是对变量的拷贝进行处理,而变量本体如果发生变化可能也不会察觉

解决:

加上volatile限定符后,每次处理都会直接从内存读取,所以可以感知变量的变化。

但是:

寄存器走了,缓存来了,但问题没那么严重

多核cpu分别有自己的缓存,对内存的操作会先通过缓存,在一个cpu对volatile变量进行操作后,会告知其他cpu对其缓存进行处理以更新该volatile变量的值,这个告知并处理的流程会损失一点实时性。

禁止编译优化

“聪明的”编译器在满足“同输入便会同输出”的as-if原则的前提下,会在编译的过程中对代码进行优化,

  • 避免丢失:使得和输出无关的代码可能被优化掉,而如果这部分代码是有意义的,便是个问题。在加上限定符后,会老老实实地编译这部分代码。
  • 保证顺序:某些和编译器优化逻辑不同的语句会被调换位置,加上后便会按照代码顺序执行。

注意:volatile不能够保证线程同步

加上该限定符后,编译的代码不会乱序,但是执行时可能碰到CPU的乱序执行,即

CPU会对没有明显依赖关系的代码进行乱序执行,但这段代码可能在另一个线程里存在依赖关系,导致原本设计好的逻辑关系不能实现。

此时有两种解决办法:

  • 1.使用c++11标准之后开始提供的的atomic类模板
#include<atomic>

atomic<bool> flag;

  • 2.手动构造happans-before语义

参考:

C/C++ 中 volatile 关键字详解

C/C++中volatile关键字介绍

C/C++ Volatile关键词深度剖析

谈谈C++的volatile关键字以及常见的误解

类型限定符volatile的更多相关文章

  1. C语言中类型限定符

    通常用类型和存储类别来描述一个变量. C90还增加了两个属性:恒常性(constancy).易变性(volatility): 分别用关键字const和volatile来声明. 这两个关键字创建的类型是 ...

  2. ISO/IEC 9899:2011 条款6.7.3——类型限定符

    6.7.3 类型限定符 语法 1.type-qualifier: const restrict volatile _Atomic 约束 2.除了指针类型(其被引用的类型是一个对象类型)之外的类型,不应 ...

  3. C 类型限定符

    C 类型限定符 1. Introduction C 语言中的大部分类型都可以用称为限定符(qualifier)的关键字 const. volatile. restrict. _Atomic 加以限定. ...

  4. CUDA1.1-函数类型限定符与变量类型限定符

    这部分来自于<CUDA_C_Programming_Guide.pdf>,看完<GPU高性能变成CUDA实战>的第四章,觉得这本书还是很好的,是一种循序渐进式的书,值得看,而不 ...

  5. GPU编程自学6 —— 函数与变量类型限定符

    深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...

  6. C:类型限定符

  7. [汇编与C语言关系]5. volatile限定符

    现在研究一下编译器优化会对生成的指令产生什么影响,在此基础上介绍C语言的volatile限定符.首先看下面的C程序: /* artificial device registers */ unsigne ...

  8. [面试]volatile类型修饰符/内存屏障/处理器缓存

    volatile类型修饰符 本篇文章的目的是为了自己梳理面试知识点, 在这里做一下笔记. 绝大部分内容是基于这些文章的内容进行了copy+整理: 1. http://www.infoq.com/cn/ ...

  9. 解决 “MoveFile”: 类型库“XXX.dll”中的标识符已经是宏;使用“rename”限定符 类型库符号与系统符号冲突问题

    今天在VS工程当中引入一个组件,编译的时候出现警告, “MoveFile”: 类型库“XXX.dll”中的标识符已经是宏:使用“rename”限定符.虽然只是一个警告,但看着实在不爽,更重要的是,警告 ...

随机推荐

  1. 002_FreeRTOS临界段代码

    (一)临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段 (二)FreeRTOS 与 临 界 段 代 码 保 护 有 关 的 函 数 有 4 个,两个是任务级的临界段代码保护,两个是中断 ...

  2. sql server 存储过程的详解

    SqlServer存储过程详解 1.创建存储过程的基本语法模板: if (exists (select * from sys.objects where name = 'pro_name')) dro ...

  3. webpack+vue+Eslint+husky+lint-staged 统一项目编码规范

    一. Eslint: 为什么我们要在项目中使用ESLint ESLint可以校验我们写的代码,给代码定义一个规范,项目里的代码必须按照这个规范写. 加入ESLint有非常多的好处,比如说可以帮助我们避 ...

  4. leetcode解题报告(4):Search in Rotated Sorted ArrayII

    描述 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...

  5. 「NOI 2018」归程「Kruskal 重构树」

    题解 Kruskal重构树:每次一条边连接两个集合,建一个新点,点权为该边边权:把这两个集合的根连向新点. 性质:(如果求的是最大生成树)叶子结点是图中实际结点:叶子到根路径上点权递减:两点间lca的 ...

  6. apt update时出现签名无法验证,公钥失效的解决办法

    错误信息如下 W: GPG error: http://ppa.launchpad.net/ondrej/php/ubuntu xenial InRelease: The following sign ...

  7. c语言 数组类型

    数组类型重命名数组类型由元素类型和数组大小共同决定数组指针是一个指针,只想对应类型的数组指针数组是一个数组,其中每个元素都是指针数组指针遵循指针运算法则指针数组拥有c语言数组的各种特性 c通过type ...

  8. Java实例化对象过程中的内存分配

    Java实例化对象过程中的内存分配: https://blog.csdn.net/qq_36934826/article/details/82685791 问题引入这里先定义一个很不标准的“书”类,这 ...

  9. ICEM-水雷

    原视频下载地址: https://yunpan.cn/cqhsvXAKUQEA4  访问密码 ef39

  10. python3 django连接mysql数据库

    在django中将模型类中的数据迁移到mysql数据库中,首先使用pip install pymysql安装pymysql库, 然后在项目中的__init__.py中添加 import pymysql ...