volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了

文章讨论了volatile关键字在C/C++编程中的重要性,特别是在中断服务程序和多线程环境下的应用。当一个变量可能在中断函数或不同线程中被修改时,使用volatile可以防止编译器进行不必要的优化,确保每次访问变量时都从内存中读取最新值,从而实现正确同步。
摘要由CSDN通过智能技术生成

被意想不到的改变?被谁改变?
1.在中断函数中被改变

2.在其他线程被改变

一般说来,volatile用在如下的几个地方:

一、 中断服务程序中修改的供其它程序检测的变量需要加 volatile;

static int i=0;

int main(void)
{
  ...
  while (1) {
    if (i) {
      dosomething();
    }
  }/* Interrupt service routine. */
void ISR_2(void)
{
      i=1;
}

程序的本意是希望ISR_2中断产生时,在main当中调用do_something函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致do_something永远也不会被调用。如果变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。

二、多任务环境下各任务间共享的标志 应该加 volatile;

在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程。

DWORD __stdcall threadFunc(LPVOID signal) 
{ 
  int* intSignal=reinterpret_cast<int*>(signal); 
  *intSignal=2; 

  while(*intSignal!=1) 
      sleep(1000); 

  return 0; 
}

该线程启动时将intSignal 置为2,然后循环等待直到intSignal 为1 时退出。显然intSignal的值必须在外部被改变,否则该线程不会退出。但是实际运行的时候该线程却不会退出,即使在外部将它的值改为1,看一下对应的伪汇编代码就明白了:

mov ax,signal 
  label: 
  if(ax!=1) 
  goto label

对于C编译器来说,它并不知道这个值会被其他线程修改。自然就把它cache在寄存器里面。记住,C 编译器是没有线程概念的!这时候就需要用到volatile。volatile 的本意是指:这个值可能会在当前线程外部被改变。也就是说,我们要在threadFunc中的intSignal前面加上volatile关键字,这时候,编译器知道该变量的值会在外部改变,因此每次访问该变量时会重新读取

原文链接:https://blog.csdn.net/breadheart/article/details/114450275

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学无止境2022

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

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

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

打赏作者

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

抵扣说明:

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

余额充值