C++——volatile关键字的学习

Stella981
• 阅读 954

首先声明一点,本文是关于volatile关键字的学习,学习内容主要是来自一些大牛的网络博客。

一篇是何登成先生的C/C++ Volatile关键词深度剖析(http://hedengcheng.com/?p=725)

一篇是chao_yu的C/C++中volatile关键字详解https://www.cnblogs.com/yc\_sunniwell/archive/2010/07/14/1777432.html)

还有一篇来自于官方文档(https://zh.cppreference.com/w/cpp/language/cv)

本文旨在于学习和记录,因此会有一些内容直接抄的上述博客,向上述博客大牛致以崇高的敬意。特此声明。

  在看代码的时候,发现有使用volatile的关键字,但是一知半解,因此搜索了一些关于volatile的相关资料。总结(摘抄)如下:

1. CV类型限定符中,const被定义为常类型,volatile 被定义为易变的类型。

_const 对象_——类型为 const-qualified 的对象,或 const 对象的非 mutable 子对象。这种对象不能修改:尝试直接这么做是编译时错误,且尝试间接这么做(例如通过到非 const 类型的引用或指针修改 const 对象)导致未定义行为。

volatile 对象——类型为 volatile-qualified 的对象,或 volatile 对象的子对象,或 const volatile 对象的 mutable 子对象。通过 volatile 限定类型泛左值表达式的每次访问(读或写操作、成员函数调用等)都被当作对于优化目的的可见副效应(即在执行的单一线程内, volatile 访问不能被优化掉或者与另一先序或后序于该 volatile 访问的可见副效应重排序。这使得 volatile 对象适用于与信号处理函数的交流,但不适于与另一执行线程交流,参阅 std::memory_order )。试图通过非 volatile 泛左值引用 volatile 对象(例如,通过到非 volatile 类型的引用或指针)会导致未定义行为。

_const volatile 对象_——类型为 const-volatile-qualified 的对象, const volatile 对象的非 mutable 子对象, volatile 对象的 const 子对象,或非 mutable 对象的 const 子对象。表现同 const 对象与 volatile 对象两者。

2.volatile的特性

2.1 易变性。 在汇编层面观察,两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是直接从内存中读取。

2.2 不可优化性。volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。相对于前面提到的第一个特性:”易变”性,”不可优化”特性可能知晓的人会相对少一些。

2.3 顺序性。C/C++ Volatile关键词前面提到的两个特性,让Volatile经常被解读为一个为多线程而生的关键词:一个全局变量,会被多线程同时访问/修改,那么线程内部,就不能假设此变量的不变性,并且基于此假设,来做一些程序设计。当然,这样的假设,本身并没有什么问题,多线程编程,并发访问/修改的全局变量,通常都会建议加上Volatile关键词修饰,来防止C/C++编译器进行不必要的优化。

3.总结

C/C++ Volatile关键词的第三个特性:”顺序性”,能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。Volatile变量与非Volatile变量的顺序,编译器不保证顺序,可能会进行乱序优化。同时,C/C++ Volatile关键词,并不能用于构建happens-before语义,因此在进行多线程程序设计时,要小心使用volatile,不要掉入volatile变量的使用陷阱之中。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这