当前位置: 首页 > 知识库问答 >
问题:

在现代C++中,volatile是否还应该用于与ISR共享数据?

李捷
2023-03-14

我已经看到了一些这样的问题,我看到了各种不同的答案,仍然不确定它们是否是最新的,是否完全适用于我的用例,所以我在这里问一下。如果是复制品请告诉我!

鉴于我正在使用C++17和gcc-arm-none-eabi-9工具链开发STM32微控制器(裸机):

我仍然需要使用volatile在ISR和main()之间共享数据吗?

volatile std::int32_t flag = 0;

extern "C" void ISR()
{
    flag = 1;
}

int main()
{
    while (!flag) { ... }
}

很明显,我应该始终使用volatile来访问内存映射的HW寄存器。

然而,对于ISR用例,我不知道它是否可以被视为“多线程”的情况。在那种情况下,人们推荐使用C++11的新线程特性(例如std::atomic)。我很清楚volatile(不优化)和atomic(安全访问)之间的区别,因此建议std::atomic的答案让我感到困惑。

对于x86系统上的“真正的”多线程,我没有看到需要使用volatile

换句话说:编译器能知道标志可以在ISR内部改变吗?如果没有,它如何在常规的多线程应用程序中知道它?

谢啦!

共有2个答案

慎懿轩
2023-03-14

编译器不知道(或不考虑)标志可以在ISR内更改。编译器不知道(或考虑)您的应用程序是常规的多线程。

atomic具有一些对抗volatile的特性。有内存模型,您可以稍微优化内存的读/写。

龙才俊
2023-03-14

这是volatile访问的主要用途之一。ISR本身不是多线程访问,因此在这里使用volatile是非常合适的。

事实上,这(连同映射到编译器无法理解的内容的读取内存)只是我所知道的两个适当的volatile用法实例

 类似资料:
  • 在 C 中实现回调函数时,我是否仍应使用 C 样式函数指针: 或者我应该使用std::函数:

  • 问题内容: 我在同一页面上有两个不同的应用程序。 我可以通过服务(或其他方式)在这两个应用之间共享数据吗? 还是不可能? (我怀疑这是不可能通过常规的角度机构实现的)-但我认为仍然值得提出… 可以使用window变量完成此操作-但我要避免这样做。 谢谢! 问题答案: 我最终以以下方式解决了该问题: 我必须承认这一解决方案并不理想,但这是我找到的最干净的解决方案。

  • 问题内容: 假设我在Linux中有一个使用共享库(文件)的应用程序。我的问题是这些库中的代码是否将在与主应用程序相同的堆中分配内存,还是使用自己的堆? 因此,例如,文件中的某些函数调用,它将使用与应用程序相同的堆管理器,还是使用另一个应用程序?同样,那些共享内存中的全局数据又如何呢?它在哪里?对于应用程序,我知道它位于bss和数据段中,但是不知道这些共享对象文件在哪里。 问题答案: 我的问题是这些

  • Spring Boot 2.3.0.Release(带有启动程序:Data、JPA、web、mysql) 轴突Spring启动器-4.2.1 每个服务在mysql服务器中使用不同的模式。 当我在激活axon框架的情况下启动spring boot服务时,在每个应用程序的数据库模式中创建了一些令牌、SAGA等表。

  • 问题内容: 在我的代码中的某些情况下,只有在定义了该函数的情况下,我最终才调用该函数,否则我不应该调用该函数。我怎样才能做到这一点? 提出此问题的另一种方法可能是:如何确定函数是否在运行时定义,如果是,则调用。 问题答案: 尽管其他答复是有用的建议(,函数指针等),但是您 不能编译 引用不存在的函数的C ++代码。至少必须 声明 函数;如果不是,您的代码将无法编译。如果没有任何内容(编译单元,某些

  • 我正在尝试实现LZ77的快速版本,我有一个关于并发编程的问题要问你。 现在我有一个和一个,两者的长度相同。该程序执行以下操作: > 主线程写入所有缓冲区,然后通知线程并等待它们完成。 单个工作线程处理缓冲区的一部分,并将结果保存在结果保持器的同一部分中。工人部分是排他性的。之后,主线程会收到通知,工作人员会暂停。 当所有的工作都暂停时,主线程读取结果持有器中的数据并更新缓冲区,然后(如果需要)过程

  • 问题内容: 使用JavaScript更改当前网页位置的首选方法是什么?我已经看到使用window.navigate和document.location了。行为上有区别吗?浏览器的实现是否有所不同? 问题答案: 是用于更改当前窗口位置的标准实现。

  • 问题内容: 在界面中添加Javadoc注释并在实现中添加非Javadoc注释是否正确? 当您自动生成注释时,大多数IDE都会为实现生成非JavaDoc注释。具体方法不应该有描述吗? 问题答案: 对于仅实现(不是覆盖)的方法,请确定为什么不这样做,尤其是如果它们是公共的。 如果您处于压倒一切的情况,并且打算复制任何文本,那么绝对不能。复制是导致差异的必经之路。结果,用户将基于检查父类型还是子类型中的