Volatile关键字的作用

Volatile是c语言中的关键字,常用于声明变量函数等,主要是为了让编译器识别到这个关键字声明的变量或者函数不被优化,因此我们要探索一下编译的优化:

1、防止编译重排序,代码如下:

编译器在编译这段代码时,并不一定会将a,b,c,d这4个变量按照func函数里的赋值顺序来赋值,而可能是随机顺序赋值的,而如果在abcd声明的时候加上volatile关键字的话,func函数赋值会严格按顺序来。

下面来举一个嵌入式开发中常遇到的可能由于编译器优化的重排序bug,如下图所示代码。

该图中如果flag和data不加关键字的话,编译器优化时可能会先取指令flag = 1;再取指令data = get_data();如果在这两条指令的中间,被中断处理函数打断执行就会出现data_handle(data)取的data是错误的值,因此给两个变量加上关键字volatile声明便可以避免这种编译器优化出现的bug。正确的做法应如下图所示。

2、去重复,代码如下:

编译器在执行上述代码时,会进行优化,去重复优化,最后会优化成下图代码:

当我们在跑多线程的时候,需要对利用线程之前需要获取一定的过程值,此时可能会因为编译器的优化而带来一些问题,因此为了代码在不通的编译器下通用,便可以加上volatile关键,确保稳定。

例如我们经常要去读写寄存器地址上的值,当我们不使用volatile关键的时候,编译器经过优化后,可能最后变成如下情况:

如果某些特定寄存器需要进行一定的时序赋值,则可能会出现问题。

3、给编译器添加屏障,其原理是利用1所说的利用volatile关键字避免重排序,

还是利用1中代码来举例,如果不直接给data和flag加上关键字,那么我们可以在两者执行的前后加一道屏障,用于确定前后顺序,如下图所示

加上这道屏障后,flag的执行只能注定比data要低一等了,不同的编译器其编译屏障的使用方法不一样,在需要时可以自行去搜索使用一下,感受其妙用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值