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_linux驱动之_register_chrdev注册字符设备

    (一)解析:register_chrdev函数和unregister_chrdev函数 (二)register_chrdev函数原型 int register_chrdev(unsigned int ...

  2. luogu 4909 [Usaco2006 Mar]Ski Lift 缆车支柱 动态规划

    可以出模拟赛T1? #include <bits/stdc++.h> #define N 5002 #define inf 1000000 #define setIO(s) freopen ...

  3. 使用scikit-learn决策树实现简单预测

    1.scikit-learn决策树算法库介绍 scikit-learn决策树算法类库内部实现是使用了调优过的CART树算法,既可以做分类,又可以做回归.分类决策树的类对应的是DecisionTreeC ...

  4. spring-boot-starter-test

    1.约定 单元测试代码写在src/test/java目录下 单元测试类命名为*Test,前缀为要测试的类名 2. 使用mock方式单元测试 Spring测试框架提供MockMvc对象,可以在不需要客户 ...

  5. form 表单提交数据和文件(fromdata的使用方法)

    <!-- 数据和文件一次性提交 --> <form class="form_meren" id="mainForm" name="m ...

  6. ubuntu 安装go

    sudo apt install golang-go

  7. 调试NTDLL加载

    1 随便切到一个进程 0: kd> !process 0 0 explorer.exePROCESS 8157e9a8 SessionId: 0 Cid: 06a4 Peb: 7ffde000 ...

  8. win10+mysql8.0安装

    一.下载 mysql8.0 windows zip包下载地址: https://dev.mysql.com/downloads/mysql/   1540951981(1).png 二.安装 1.解压 ...

  9. Flutter移动电商实战 --(17)首页_楼层区域的编写

    1.楼层标题组件 该组件非常简单,只接收一个图片地址,然后显示即可: class FloorTitle extends StatelessWidget { final String picture_a ...

  10. RotateDrawable

    用来对Drawable进行旋转,也是通过setLevel来控制旋转的,最大值也是:10000 相关属性如下: fromDegrees:起始的角度,,对应最低的level值,默认为0 toDegrees ...