gpt4 book ai didi

c - 静态全局变量和静态 volatile 变量有什么区别?

转载 作者:太空狗 更新时间:2023-10-29 16:23:13 26 4
gpt4 key购买 nike

我在文件范围内使用了一个静态全局变量和一个静态 volatile 变量,

两者都由 ISR 和主循环更新,主循环检查变量的值。

此处在优化期间,全局变量和 volatile 变量都没有被优化。因此,不是使用 volatile 变量,而是使用全局变量来解决问题。

那么用全局变量代替volatile好不好?

使用 static volatile 的任何特定原因?

任何示例程序都是值得赞赏的。

提前致谢..

最佳答案

首先让我提一下,静态全局变量与全局变量相同,只是您将变量限制在文件的范围内。 IE。您不能通过 extern 关键字在其他文件中使用此全局变量。

因此,您可以将问题简化为全局变量与 volatile 变量。

现在介绍 volatile:

const一样,volatile也是类型修饰符。

创建 volatile 关键字是为了防止可能导致代码不正确的编译器优化,特别是在存在异步事件时。

声明为 volatile 的对象可能不会在某些优化中使用。

系统总是在使用 volatile 对象时读取它的当前真实值,即使先前的指令从同一对象请求值也是如此。此外,对象的值在赋值时立即写入。这意味着不会将 volatile 变量缓存到 CPU 寄存器中。

Dr. Jobb's has a great article on volatile .

这是 Jobb 博士文章中的一个示例:

class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};

如果编译器发现 Sleep() 是一个外部调用,它会假设 Sleep() 不可能改变变量 flag_ 的值。所以编译器可能会将 flag_ 的值存储在一个寄存器中。在那种情况下,它永远不会改变。但是如果另一个线程调用唤醒,第一个线程仍然在从 CPU 的寄存器中读取。 Wait() 永远不会唤醒。

那么为什么不从不将变量缓存到寄存器中并完全避免这个问题呢?事实证明,这种优化确实可以为您整体节省大量时间。因此 C/C++ 允许您通过 volatile 关键字显式禁用它。

上面的事实 flag_ 是一个成员变量,而不是一个全局变量(也不是静态全局变量)并不重要。即使您正在处理全局变量(和静态全局变量),示例后的解释也给出了正确的推理。

一个常见的误解是声明变量 volatile 足以确保线程安全。对变量的操作仍然不是原子的,即使它们没有“缓存”在寄存器中

带指针的 volatile :

volatile 与指针,就像 const 与指针一样。

volatile int * 类型的变量表示指针指向的变量是易变的。

int * volatile 类型的变量意味着指针本身是易变的。

关于c - 静态全局变量和静态 volatile 变量有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/346306/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com