Gir*_*nte 3 c embedded driver volatile
我知道volatile关键字会阻止编译器优化变量,并在读取时从内存中读取它.除了内存映射寄存器之外,我们需要使用volatile的所有情况是什么?给定一个符合标准的编译器,我是否必须在两种情况下都将test_var声明为volatile?
int test_var=100;
void func1()
{
test_var++;
}
Run Code Online (Sandbox Code Playgroud)
extern int test_var;
void func2()
{
if(test_var==100)
{
....
}
}
Run Code Online (Sandbox Code Playgroud)
int test_var=100;
void func1()
{
}
Run Code Online (Sandbox Code Playgroud)
extern int test_var;
void func2()
{
if(test_var==100)
{
....
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
内存映射I/O是C中唯一的通用用途volatile.*)
使用POSIX信号,a volatile也可以与这样的类型一起使用sig_atomic_t:
volatile sig_atomic_t signal_occured = 0;
Run Code Online (Sandbox Code Playgroud)
您的任何一个场景都不需要volatile.如果您感兴趣的是保证不同编译单元之间的值更新,请参阅tofro的评论,extern已经保证.特别是,volatile它不是 C中线程同步的正确工具.它只会引入错误,因为,正如你所说,它确实需要对变量进行实际的读写访问,但它并没有强制执行它们对线程的正确排序(这是缺少内存障碍,谷歌的详细信息).
请注意,这与volatile设计为在线程之间工作的其他语言不同.
在嵌入式系统中,volatile当与原始读取/写入的数据类型组合时,可能足以在ISR(中断服务例程)和主程序之间进行通信,就像sig_atomic_tPOSIX信号一样.请参阅编译器的文档.
*)C标准提到了这一点,以及"异步中断函数"的用例,仅在脚注中,因为内存映射的I/O超出了语言的范围.该语言只是volatile以一种使其适合内存映射I/O的方式定义语义.