zoukankan      html  css  js  c++  java
  • C/C++中关键字volatile用法

    1、为什么使用volatile?

    C/C++中的volatile关键字和const对应,用来修饰变量,通常用于建立语言级别的memory barrier,volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,例如:操作系统、硬件或其它线程等,遇到该关键字声明的变量,编译器将对访问该变量的代码不再进行优化,从而可以提供对特殊地址的稳定访问。当要求使用volatile声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存,例如:

    volatile int i = 10;
    int a = i;
    ...
    //其它代码,并未明确告诉编译器,对i进行过操作
    int b = i;

    volatile关键词指出变量i是随时可能发生变化的,每次使用它的时候必须从i的内存地址中读取,因此,编译器生成的汇编代码会重新从i的内存地址读取数据放在变量b中。而优化的做法是,由于编译器发现两次从i读数据的代码之间没有对i进行过操作,它会自动把上次读取的数据放在b中,而不是重新从变量i的内存地址中读取数据,这样一来,如果变量i是一个寄存器变量或者表示一个端口数据,就很容易出错,volatile类型修饰符可以保证对特殊地址的稳定访问。

    一般来说,volatile类型修饰符用在如下几个地方:

    • 中断服务程序中修改的供其它程序检测的变量需要加volatile;
    • 多任务环境下各任务间共享的标志应该加volatile;
    • 存储器映射的硬件寄存器通常要加volatile类型修饰,每次对寄存器的读写都可能有不同意义。

    2、volatile指针

    和const类型修饰符类似,const有常量指针和指针常量的说法,volatile也有相应的概念:

    修饰由指针指向的对象,数据是const或volatile的:

    const char *cp;
    volatile char *vp;

    修饰指针自身的值,指针的指向是const或volatile的:

    char* const p1;
    char* volatile p2;

    3、多线程下的volatile

    当两个线程都要用到某一个变量,并且该变量的值会被改变时,应该使用volatile类型限定符声明,防止编译器优化将变量从内存装入到CPU寄存器中,如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,从而造成程序的错误执行,使用volatile修饰变量,可以让程序在执行时,每次操作变量都从内存中真正取出,而不是直接使用已经存在寄存器中的值,如下:

    volatile BOOL bStop = FALSE;

    在其中一个线程中,如下:

    while (!bStop)
    {
        ...
        ...
    }
    bStop = FALSE;
    return;

    在另外一个线程中,需要终止上面的线程循环:

    bStop = TRUE;
    while (bStop);  //等待上面的线程终止,如果bStop不使用volatile声明,那么循环将是一个死循环,
    因为bStop已经读取到了寄存器中,寄存器中bStop的值不会变成TRUE,当加上volatile后,程序在执行时,
    每次都将从内存中读取bStop的值,不会陷入死循环

    volatile关键字用来设定某个对象的存储位置是在内存中,而不是寄存器,对于一般的对象,编译器可能会将其的拷贝放在寄存器中,以加快指令的执行速度,因此,对于多线程下的共享变量,注意需要使用volatile进行修饰。

    原文地址:

    https://www.runoob.com/w3cnote/c-volatile-keyword.html

  • 相关阅读:
    Codeforces Gym 100571A A. Cursed Query 离线
    codeforces Gym 100500 J. Bye Bye Russia
    codeforces Gym 100500H H. ICPC Quest 水题
    codeforces Gym 100500H A. Potion of Immortality 简单DP
    Codeforces Gym 100500F Problem F. Door Lock 二分
    codeforces Gym 100500C D.Hall of Fame 排序
    spring data jpa 创建方法名进行简单查询
    Spring集成JPA提示Not an managed type
    hibernate配置文件中的catalog属性
    SonarLint插件的安装与使用
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/13582982.html
Copyright © 2011-2022 走看看