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

2023-11-22

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

1)注册

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

2) ISR

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++;
}

我明白为什么编译器会错误地优化while在情况 1) 如果volatile不存在,因为变量更改是从hardware,编译器可能看不到变量的任何更改code.

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

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

另外,情况 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 寄存器来生成更快的代码once并在循环或函数中使用该缓存值。访问 RAM 可能比访问 CPU 寄存器慢数十倍。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • 在 PowerShell 中写入时锁定文件

    我有一个要求 其中一个进程连续写入特定文件夹中的文件 同时 另一个脚本将文件从该文件夹移动到另一个文件夹 但是 当第一个进程正在写入文件时 不得移动文件 PowerShell中是否有任何进程 函数可以满足这个要求 在 Powershell
  • 在 pyvis 中我总是收到此错误:“AttributeError:'NoneType'对象没有属性'render'”

    我想使用最新版本的 pyvis 和 python 版本 3 9 6 进行网络可视化 from pyvis network import Network g Network g add node 0 g add node 1 g add ed
  • 如何在命名空间内创建私有变量?

    对于我的 Web 应用程序 我正在 JavaScript 中创建一个命名空间 如下所示 var com example com example func1 function args com example func2 function a
  • PermGen 内存不足原因

    我经常在我的环境中检测 PermGen 中的 OOM java 6 jboss 4 2 3 不是一个大型网络应用程序 我知道 String intern 问题 但我没有足够的有价值的用途 MaxPermGen 大小的增加并不费力 从 128
  • 如何输出矩阵维度及其内容?

    是否可以使 GNU Octave 输出矩阵尺寸及其内容 例如 它应该产生某种东西 像这样 octave 1 gt X 1 2 3 4 X 2x2 1 2 3 4 octave 2 gt X 1 ans 1x2 1 2 在 MATLAB 中
  • 在java应用程序中保存用户设置的最佳方法是什么?

    在java桌面应用程序中安全保存用户设置的最佳方法是什么 例如 如果我想保存 Ftp 帐户设置 最好的方法是什么 Thanks The 首选项 API是存储用户和系统首选项的好方法 如果您想存储密码 则必须对其进行加密 这是一篇不错的文章
  • 如何在打字稿中将一个枚举映射到另一个枚举?

    我想将一个具有枚举类型的对象的属性映射到另一个具有其他枚举类型的对象的属性 我尝试过type1 a as Enum2 or Enum2 type1 a 没有成功 这是我的简化代码问题 enum Enum1 N 0 A 1 B 2 enum
  • 使用 Espresso 时出现 NullPointer 异常

    我正在尝试使用浓缩咖啡 但我收到了这个错误 如果我缺少一些代码 我就没有 任何想法都将受到高度赞赏 错误日志 java lang NullPointerException No instrumentation registered Must
  • 使用 Vee-Validate 验证提交时的子输入组件

    我目前正在尝试创建一个包含多个 输入字段 组件的注册表单 这些组件都需要在按下 提交 后进行验证 目前 当其中的文本发生更改时 它们都会自行验证 但我发现很难对所有输入字段进行全局调用以验证所有输入字段 我想要实现的目标如下 http ve
  • PostgreSQL:加速数百万行表中的 SELECT 查询

    我有一个包含 gt 450 万行的表 我的SELECT查询对于我的需求来说太慢了 该表是用以下命令创建的 CREATE TABLE all legs carrier TEXT dep hub TEXT arr hub TEXT dep dt
  • 使用 Passport-saml 注销:req.logout() 或 Strategy.logout(),或两者?

    我有一个关于使用 Passport saml 进行身份验证时注销用户的正确方法的问题 使用 Passport saml 的示例脚本显示注销如下 app get logout function req res req logout res r
  • 无法在打字稿中导入 svg 文件

    In typescript tsx 文件我无法使用以下语句导入 svg 文件 import logo from logo svg 转译器 说 ts cannot find module logo svg 我的 svg 文件只是
  • 导出签名的应用程序而不“优化”png图像

    当我从 eclipse 导出 apk 时 它会压缩所有 png 图像 例如 一张 4 6 KB 的 png 在 apk 中变成了 2 15 KB 不过我更喜欢使用优化 png 文件tinypng在构建 apk 之前 这会生成更小的文件 同样
  • Composer 没有为包生成 .git 文件夹

    这很奇怪 似乎是我错过的一些小事 前几天 当我composer install我得到了自己的供应商目录 git 这允许我进行更改并更新我自己的打包存储库 今天跑步后composer install the git每个包文件夹内的目录丢失 我
  • 烛台多个 Y 值

    我的任务是在 Windows 窗体中使用 MSChart 制作烛台图 我已经成功地制作了 3D 条形图 没有任何问题 但在互联网 微软的源代码 WinSamples 和大量的搜索之后 我找不到创建烛台图的正确方法 可以帮助我的是一个清楚的例
  • mat 不是数值元组:openCV 错误

    我写下了一段显示错误的代码 但我没有得到它 请帮助 它的显示垫不是数字元组 import cv import cv2 capture cv2 VideoCapture j 3gp while 1 frame1 capture read gr
  • java复制构造函数和继承

    经过一番搜索后 我没有找到有关复制构造函数和继承的问题的任何好的答案 我有两个班级 用户和实习生 Trainee继承自User 并为Trainee添加两个String参数 现在我成功地创建了 User 的复制构造函数 但我对 Trainee
  • 将 Visual Studio 2012 导出为 2010 sln 格式

    我的老师抱怨他无法在 VS2010 环境中读取 VS2012 格式 我在设置等中环顾四周 但找不到任何东西 如何将 VS2010 可读格式的项目提供给我的老师 手动修改sln 备份您的项目文件夹 复制 粘贴到另一个位置 例如名为 backu
  • 无法安装 npm 包:“npm ERR!errno -4048”

    我正在尝试安装 npm 包 node xmpp server 但安装失败 以前 当我尝试安装全局安装而不是本地安装的软件包时 但现在根本不安装 我以管理员身份运行 bash I ran npm install node xmpp serve
  • ISR和多线程程序中的C'Volatile'关键字?

    我读到了 C 的用法volatile内存映射硬件寄存器 ISR 和多线程程序中的关键字 1 注册 uint8 t volatile pReg while pReg 0 do sth pReg point to status register