zoukankan      html  css  js  c++  java
  • 关于volatile的一些思考C++

    在c++中,volatile用与修饰容易变动的变量,通常用于多线程的标志,编译器会存在代码优化,假如在同一个大括号中没有修改这么一个参数,那么编译器很可能在读取这个值的时候使用的是快取的方法,即将这个值在这段括号中如果没有改变的话,直接拷贝一份放在内存中,每次都从这里取而不是去寄存器取值,而对于多线程的程序,由于代码没在同一个括号下面,编译器在编译的时候可能无法识别,误以为这个值并没有改变,那么将会产生意外的结果,

    简单地说就是防止编译器对代码进行优化.比如如下程序:
    1
    2
    3
    4
    XBYTE[2]=0x55;
    XBYTE[2]=0x56;
    XBYTE[2]=0x57;
    XBYTE[2]=0x58;
    对外部硬件而言,上述四条语句分别表示不同的操作,会产生四种不同的动作,但是编译器却会对上述四条语句进行优化,认为只有XBYTE[2]=0x58(即忽略前三条语句,只产生一条机器代码)。如果键入volatile,则编译器会逐一的进行编译并产生相应的机器代码(产生四条代码).
    1
    2
    3
    4
    5
    6
    7
    int square( volatile int *ptr )
    {
        int a,b;
        a = *ptr;
        b = *ptr;
        return a * b;
    }
    由于*ptr的值可能在两次取值语句之间发生改变,因此a和b可能是不同的。结果,这段代码可能返回的不是你所期望的平方值!正确的代码如下:
    1
    2
    3
    4
    5
    6
    long square( volatile int *ptr )
    {
        int a;
        a = *ptr;
        return a * a;
    }
    讲讲个人理解:
    关键在于两个地方:
    编译器的优化(请高手帮我看看下面的理解)
    在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后再取变量值时,就直接从寄存器中取值;
    变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致
    变量在因别的线程等而改变了值,该寄存器的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致
    当该寄存器在因别的线程等而改变了值,原变量的值不会改变,从而造成应用程序读取的值和实际的变量值不一致

    所以引用百度的一段话来指导使用条件:

    1. volatile对应的变量可能在你的程序本身不知道的情况下发生改变
    2. 比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
    3. 你自己的程序,是无法判定何时这个变量会发生变化
  • 相关阅读:
    Eclipse护眼技巧
    Maven搭建SSM框架(Spring+SpringMVC+MyBatis)
    Spring之各jar包作用
    Maven新建web项目jsp报错
    js金额转大写(万元为单位)
    linux常用指令
    ie8下数组不支持indexOf方法解决方法
    string,stringBuffer,stringBuilder的比较
    input限制输入
    spring boot Mybatis --maven
  • 原文地址:https://www.cnblogs.com/luomingchuan/p/3661390.html
Copyright © 2011-2022 走看看