17 volatile,让我保持原样
嵌入式开发中的常见情形
实例分析
-
设备启动及初始化
//device.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int g_ready = 0;
void* init_device(void* args)
{
sleep(5);
g_ready = 1;
printf("init_device() - device status : g_ready = %d\n", g_ready);
}
void launch_device()
{
pthread_t tid = 0;
pthread_create(&tid, NULL, init_device, NULL);
}//main.c
#include <stdio.h>
#include <pthread.h>
extern const int g_ready;
int main()
{
launch_device();
while( g_ready == 0 )
{
sleep(1);
printf("main() - launching device : g_ready = %d\n", g_ready);
}
printf("main() - device status : g_ready = %d\n", g_ready);
return 0;
} -
问题分析
- 编译优化时,编译器根据当前文件进行优化
- 编译器能够发现变量“不可能”被改变(const 全局变量)
- 为了效率上的提高,编译将变量值进行缓存
- 缓存的方式为:把变量值从内存中读取进入寄存器
- 每次访问变量时直接从寄存器读取对应值
-
解决方案
- 使用volatile修饰可能被“意外”修改的变量(内存)
- volatile修饰的变量是一种“易变的”变量
- volatile可理解为“编译器警告指示字”
- volatile告诉编译器必须每次去内存中取变量值
- 使用volatile修饰可能被“意外”修改的变量(内存)
编程实验
-
使用volatile修饰变量
-
问题
如何理解const和volatile同时修饰变量?在语义上是否矛盾?
-
const和volatile
- const表示被修饰的变量不能出现在赋值符号左边
- volatile表示使用变量时直接从内存取值
- const和volatile同时修饰变量时互不影响其含义
小结
- 编译优化时,编译器只根据当前文件进行优化
- 编译器的优化策略可能造成一些“意外”
- volatile强制编译器必须每次从内存中取变量值
- const和volatile同时修饰变量时互不影响其含义