1、当一个变量可能会被意想不到的更新时,要使用volatile来声明该变量,告诉编译器它所修饰的变量的值可能会在任何时刻被意外的更新。

2、语法

  volatile int foo;
  int volatile foo;

  

  volatile int * foo; 
       int volatile * foo;

  

  int * volatile foo;

  int volatile * volatile foo;

3、场景

  1)并行设备的硬件寄存器(如状态寄存器)

  假设我们有一个8位的状态寄存器映射在地址0x1234上。系统需要我们一直监测状态寄存器的值,直到它的值不为0为止。通常错误的实现方法是:

UINT1 * ptr = (UINT1 *) 0x1234; 
// Wait for register to become non-zero.等待寄存器为非0值
while (*ptr == 0);
// Do something else.作其他事情

汇编代码:

    mov ptr, #0x1234

    mov a, @ptr

    loop bz loop  编译器认为变量值总是不变的,不必要到内存中读取它,使用一个无限循环来结束

正确:

    UINT1 volatile * ptr = 
    (UINT1 volatile *) 0x1234;

    对应的汇编代码为:
    mov ptr, #0x1234
    loop mov a, @ptr 
    bz loop

  2)中断处理程序

中断处理程序经常负责更新一些在主程序中被查询的变量的值。例如,一个串行通讯中断会检测接收到的每一个字节是否为ETX信号(以便来确认一个消息帧的结束标志)。如果其中的一个字节为ETX,中断处理程序就是修改一个全局标志。一个错误的实现方法可能为:

  int etx_rcvd = FALSE; 
  void main()
  {
  ...
  while (!ext_rcvd)    访问的是ext_rcvd备份的寄存器中的值
  {
  // Wait
  }
  ...
  } 
  interrupt void rx_isr(void)
  {
  ...
  if (ETX == rx_char)
  {
  etx_rcvd = TRUE;
  }
  ...
  }

  3)多线程应用程序

在实时操作系统中,除去队列、管道以及其他调度相关的通讯结构,在两个任务之间采用共享的内存空间(就是全局共享)实现数据的交换仍然是相当常见的方法。当你将一个优先权调度器应用于你的代码时,编译器仍然不知道某一程序段分支选择的实际工作方式以及什么时候某一分支情况会发生。这是因为,另外一个任务修改一个共享的全局变量在概念上通常和前面中断处理程序中提到的情形是一样的。所以,(这种情况下)所有共享的全局变量都要被声明为 volatile。例如:

int cntr; 
void task1(void)
{
cntr = 0;
while (cntr == 0)
{
sleep(1);
}
...

void task2(void)
{
...
cntr++;
sleep(10);
...
}

  4)利用for循环去延时的程序

Volatile的应用场景的更多相关文章

  1. 【Java线程】volatile的适用场景

    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性 ...

  2. volatile的适用场景

    volatile保证线程间的数据是可见的(共享的),但不保证数据同步 volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有 ...

  3. volatile的使用场景

    单词解释: 乱序执行:指CPU对代码的执行顺序进行乱序优化,但保证各执行代码单元的顺序按指令顺序排列.以达到充分利用处理器的各处理单元的目的.(可以理解成:一个任务有不同的执行单元,这些单元之间有一定 ...

  4. JAVA锁和volatile的内存语义&volatile的使用场景

    JAVA锁的内存语义 当线程释放锁时,JMM(Java Memory Model)会把该线程对应的本地内存中的共享变量刷新到主内存中. 当线程获取锁时,JMM会将该线程对应的本地内存置为无效.从而使得 ...

  5. volatile有什么用?能否用一句话描述volatile的应用场景

    volatile保证内存可见性和禁止指令重排.volatile用于多线程环境下的单次操作(单次读或者单次写).volatile关键字不能提供原子性.     volatile关键字为实例域的同步访问提 ...

  6. volatile 有什么用?能否用一句话说明下 volatile 的应用场景?

    volatile 保证内存可见性和禁止指令重排. volatile 用于多线程环境下的单次操作(单次读或者单次写).

  7. java volatile关键字作用及使用场景

    1. volatile关键字的作用:保证了变量的可见性(visibility).被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象.如以下代码片段,isShut ...

  8. 【并发编程】Volatile原理和使用场景解析

    目录 一个简单列子 Java内存模型 缓存不一致问题 并发编程中的"三性" 使用volatile来解决共享变量可见性 volatile和指令重排(有序性) volatile和原子性 ...

  9. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

随机推荐

  1. 2018-2019-2 网络对抗技术 20165212 Exp6 信息搜集与漏洞扫描

    2018-2019-2 网络对抗技术 20165212 Exp6 信息搜集与漏洞扫描 原理与实践说明 1.实践原理 信息搜集:渗透测试中首先要做的重要事项之一,搜集关于目标机器的一切信息 间接收集 D ...

  2. OpenCV 3.4.2 环境搭建(适用于Ubuntu 一键安装)

    前面的话 最近决定要好好地学习一下OpenCV,Ubuntu系统上简单地搭建了OpenCV环境,(Windows的搭建方法移步到window10的搭建方法),千里之行始于足下,不积跬步无以至千里,在这 ...

  3. C语言实现简单的停车场管理系统

    问题描述:停车场是一个能放n辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放.若车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入.当停车场中的车离开时,由于通道窄,在它后面呢 ...

  4. 一个机器绑两个IP可能存在的问题

    1.同一网段两个ip 无法绑到一个机器上. 因为会生成两条该网段路由,两个路由用于同网段报文相应,而实际ip选路时只会选择其中一条路由(估计会选择前面那一条)从一个网卡走.这样不管哪个网卡来的局域网内 ...

  5. restful swagger api java go

    rest框架使用swagger api,接口越来越多后性能会很差,如何优化? - 知乎https://www.zhihu.com/question/59349319 golang restful 框架 ...

  6. Java基础 hello world基础实例

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

  7. composer 安装以及使用教程

    CentOS 7 安装 Composer: composer 官方下载文档:https://getcomposer.org/download/ 首先 centos 必须安装 php-cli,也就是在命 ...

  8. Docs-.NET-C#-指南-语言参考-关键字:C# 关键字

    ylbtech-Docs-.NET-C#-指南-语言参考-关键字:C# 关键字 1.返回顶部 1. C# 关键字 2017/03/07 关键字是预定义的保留标识符,对编译器有特殊意义. 除非前面有 @ ...

  9. Vue事件 定义方法执行方法 获取数据 改变数据 执行方法传值 以及事件对象

    <template> <div id="app"> <!-- <img v-bind:src='url' /> <img :src= ...

  10. ISO/IEC 9899:2011 条款6.8.6——跳转语句

    6.8.6 跳转语句 语法 1.jump-statement: goto    identifier    ; continue    ; break    ; return    expressio ...