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. SpringContextHolder 作用

    以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext. 使用方式.在启动类里添加Bean package com.y ...

  2. C格式字符串转为二叉树

    最近在LeetCode做题,二叉树出现错误时不好排查,于是自己写了一个函数,将前序遍历格式字串转换成二叉树. 形如 "AB#D##C##" 的字符串,"#"表示 ...

  3. cmd命令net和sc

    来看windows中启动和关闭服务的方法:在cmd下可有两种方法打开,分别是net和sc. 1.net用于打开没有被禁用的服务, NET命令是功能强大的以命令行方式执行的工具. 它包含了管理网络环境. ...

  4. python中list和dict

    字典(Dictionary)是一种映射结构的数据类型,由无序的“键-值对”组成.字典的键必须是不可改变的类型,如:字符串,数字,tuple:值可以为任何python数据类型. 1.新建字典 1 2 3 ...

  5. 多个请求共用一个Servlet(JavaWEB)

    我们在对JavaWEB工程进行开发的时候,我们经常会遇到这样一个问题,在jsp中发送到Servlet的每一个请求都要写一个对应的Servlet,这样会造成一个工程完成下来需要写几十个Servlet,那 ...

  6. python脚本使用源码安装不同版本的python

    # coding=utf-8 import os import sys # 判断是否是root用户 if os.getuid() == 0: pass else: print('当前用户不是root用 ...

  7. 测试一下windowsLiveWriter

    一个是看看这个东西能不能发布出博客,还有一个就是准备开始写博客了,所以随便写个作为开始吧,我不想多说什么目标啊,什么的,所以就这一句简单的一句话就够了.

  8. setInterval调用ajax回调函数不执行的问题

    setInterval调用ajax回调函数不执行 1.首先检查你的setInterval()函数写法是否正确 参考写法 // 检查是否支付成功 var isPayRequest=false; var ...

  9. ES6深入浅出-6 ES 6 模块-1.模块化速学

    把模块先默认认为是豆腐块 为什么前端需要模块? 没有模块的方式 预览这个html页面     一共200行js代码 前100行在做一件事 ,另外100行在做另一件事,这样就是两个模块 main.js来 ...

  10. 三种构建方式:Makefile、scons、scons cmake+ninja

    三种构建方式: Makefile scons cmake+ninja https://ninja-build.org