gpt4 book ai didi

ISR 和多线程程序中的 C 'Volatile' 关键字?

转载 作者:太空狗 更新时间:2023-10-29 17:00:59 24 4
gpt4 key购买 nike

我阅读了 C volatile 关键字在内存映射硬件寄存器、ISR 和多线程程序中的用法。

1) 注册

uint8_t volatile * pReg;
while (*pReg == 0) { // do sth } // pReg point to status register

2) 情报服务侦察

int volatile flag = 0;
int main()
{
while(!flag) { // do sth }
}
interrupt void rx_isr(void)
{
//change flag
}

3) 多线程

int volatile var = 0;
int task1()
{
while (var == 0) { // do sth }
}
int task2()
{
var++;
}

如果 volatile 不存在,我明白为什么编译器会在情况 1 中错误地优化 while,因为变量更改是由 硬件,编译器可能看不到代码对变量所做的任何更改。

但是对于情况 2) 和 3),为什么需要 volatile?在这两种情况下变量都被声明为global,并且编译器可以看到它被用于多个地方地方。那么,如果变量不是 volatile,编译器为什么要优化 while 循环呢?

是不是因为编译器的设计不知道“异步调用”(在 ISR 的情况下)或多线程?但这不可能,对吧?

另外,case 3) 看起来像一个多线程中的普通程序,没有volatile 关键字。假设我向全局变量添加了一些锁定(没有 volatile 关键字):

int var = 0;
int task1()
{
lock(); // some mutex
while (var == 0) { do sth }
release()
}
int task2()
{
lock();
var++;
release();
}

我觉得很正常。那么在多线程中我真的需要 volatile 吗? 我以前怎么没见过在多线程程序中添加volatile限定符来避免优化

最佳答案

使用 volatile 关键字的要点是防止编译器生成使用 CPU 寄存器作为表示变量的更快方法的代码。这会强制编译代码在每次访问变量时访问 RAM 中的确切内存位置,以获取它的最新值,该值可能已被另一个实体更改。通过添加 volatile,我们确保我们的代码知道任何其他人(如硬件或 ISR)对变量所做的任何更改,并且不会发生一致性问题。

在没有 volatile 关键字的情况下,编译器尝试通过将变量的内容从 RAM 读取到 CPU 寄存器一次并在循环中使用该缓存值来生成更快的代码或功能。访问 RAM 可能比访问 CPU 寄存器慢数十倍。

我对第 1 项和第 2 项有经验,但我认为您不需要在多线程环境中将变量定义为 volatile。添加锁定/解锁机制是解决同步问题所必需的,与 volatile 的含义无关。

关于ISR 和多线程程序中的 C 'Volatile' 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12738672/

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