C:25---volatile关键字

一、先来看一个例子

  • 在C/C++中,一个简单的自加操作需要涉及三个步骤:
    • 第一步:将值从内存(RAM)中取到寄存器中
    • 第二步:在寄存器中将值增加
    • 第三步:将增加后的值重新写入内存

  • 测试的代码如下:
#include <stdio.h>
 
int i = 0;
int main()
{
    i++;
    return 0;
}
  • 上面程序的汇编代码如下所示,因此一个i++对应的操作是:
    • 1.把变量i从内存(RAM)加载到寄存器
    • 2.把寄存器的值加1
    • 3.把寄存器的值写回内存(RAM)

  • 因此,如果在多任务/多线程的环境下,两个不同的线程中对同一个变量进行++操作,可能导致变量最终只增加了1。如下图所示:

二、volatile关键字

  • 通过上面的例子,现在再来介绍volatile关键字就更加容易了。通过上面我们可以看到,编译器会对变量的操作进行优化,会将RAM(内存)中的值先赋值到寄存器中(寄存器的效率高于RAM),然后在寄存器中进行操作,再写入内存中。但是在多任务/多线程的情况下,这显然会发生错误
  • volatile关键字的作用就是:防止编译器进行上面的优化,每次读取数据的时候直接从内存中读,而不是从寄存器中进行读

三、几点注意事项

const与volatile

  • const关键字可以和volatile关键字一起使用
  • 它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它

指针与volatile

  • 指针可以是volatile的
  • 下面的函数是错误的
int square(volatile int *ptr)
{
    return *ptr * *ptr;
}
  • 该程序的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
    int a,b;
    a = *ptr;
    b = *ptr;
    return a * b;
}
  • 由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
    int a;
    a = *ptr;
    return a * a;
}

四、附加:原子操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值