std::memory_order 和指令顺序,澄清

2024-03-15

这是一个后续问题this one https://stackoverflow.com/questions/59626494/understanding-memory-order-acquire-and-memory-order-release-in-c11/59629166#59629166.

我想准确地弄清楚指令顺序的含义,以及它是如何受到std::memory_order_acquire, std::memory_order_release etc...

在我链接的问题中,已经提供了一些细节,但我觉得提供的答案实际上并不是关于顺序(这更多是我想要的),而是有点激励为什么这是必要的等。

我将引用相同的示例作为参考

#include <thread>
#include <atomic>
#include <cassert>
#include <string>

std::atomic<std::string*> ptr;
int data;

void producer()
{
    std::string* p  = new std::string("Hello");
    data = 42;
    ptr.store(p, std::memory_order_release);
}

void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_acquire)))
        ;
    assert(*p2 == "Hello"); // never fires
    assert(data == 42); // never fires
}

int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}

简而言之,我想弄清楚两行的指令顺序到底发生了什么

ptr.store(p, std::memory_order_release);

and

while (!(p2 = ptr.load(std::memory_order_acquire)))

根据文档重点关注第一个

...当前线程中的读取或写入操作在此存储之后不能重新排序...

我看了一些演讲来理解这个排序问题,我明白为什么它现在很重要。我还不太清楚编译器如何翻译顺序规范,我认为文档给出的示例也不是特别有用,因为在运行的线程中进行存储操作之后producer没有其他指令,因此无论如何都不会重新排序。然而,我也可能误解了,它们是否可能意味着等效的组装

std::string* p  = new std::string("Hello");
data = 42;
ptr.store(p, std::memory_order_release);

翻译的前两行将永远不会在原子存储之后移动? 同样,在运行生产者的线程中,是否有可能在原子加载之前没有任何断言(或等效程序集)被移动?假设我在存储之后有第三条指令,那些已经在原子加载之后的指令会发生什么?

我还尝试编译此类代码以保存中间汇编代码-S旗帜,但它很大,我无法真正弄清楚。

再次澄清,这个问题是关于如何排序的,而不是关于为什么这些机制有用或必要的。


我知道,当谈到内存排序时,人们通常会试图争论操作是否可以重新排序以及如何重新排序,但在我看来这是错误的方法! C++ 标准没有说明如何重新排序指令,而是定义了发生在关系之前,它本身基于顺序之前、同步和线程间发生之前关系。

从存储释放读取值的获取加载同步于获取负载,因此建立发生前关系。由于发生在关系之前的传递性,在存储释放之前“排序”的操作也“在获取加载之前发生”。关于使用原子实现的正确性的任何争论都应该始终依赖于发生之前关系。是否以及如何对指令进行重新排序仅仅是应用先于关系规则的结果。

有关 C++ 内存模型的更详细解释,您可以查看C/C++ 程序员的内存模型 https://arxiv.org/abs/1803.04432.

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

std::memory_order 和指令顺序,澄清 的相关文章

  • 在 C# 中按元素相乘数组具有意想不到的性能

    我想找到按元素相乘两个数组的最佳方法 这是更广泛项目的一部分 其中性能而不是唯一的考虑因素 我今天开始用 C Linqpad 编写一些函数 因此它还没有以任何方式进行优化 下面代码的输出如下 Environment ProcessorCou
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 如何在 C# 控制台应用程序中将修饰符(ctrl、alt、shift)按键捕获为单个按键?

    Console ReadKey 仅在按下 正常 键时捕获输入 然后将修饰符 如果有 附加为键信息的一部分 如何将单个修饰键注册为输入 提供了一种解决方案这个链接 https blogs msdn microsoft com toub 200
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • vs2008 c#:Facebook.rest.api如何使用它来获取好友列表?

    如何在此基础上取得进一步的进步 获取好友列表的下一步是什么 string APIKey ConfigurationManager AppSettings API Key string APISecret ConfigurationManag
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F

随机推荐

  • 如何从 Mesos 框架 Scheduler 类读取 mesos 任务 stdout/stderr?

    我正在开发一个 Mesos 框架 它工作得很好 我唯一的问题是我无法从 Scheduler 类内部读取任务 stdout 或 stderr 我在下面提供了一个代码示例 我想读取已完成任务的标准输出和标准错误 最好在 statusUpdate
  • 10e 表示法与变量一起使用吗?

    我想知道如何在 python 2 7 9 中使用变量的 10eX 表示法 就文字而言 10eX 给出 10 X 00000 浮点数 然而 我想使用一些变量而不是文字 但它不起作用 如果可以的话 我应该进行什么语法更改或者是否有其他方法可以这
  • 代码块、单个项目、许多可执行文件

    I use 代码 块 http en wikipedia org wiki Codeblocks和 C 我的项目应该构建多个可执行文件 一组使用共享库的小工具 如何设置 CB 生成多个二进制文件 每个二进制文件都有自己的main 看看Cod
  • 如何为我的 bool 属性正确实现 INotifyPropertyChanged 并绑定到 CheckBox.IsChecked?

    这里是新手 我一直在尝试围绕数据绑定进行思考 并想尝试将视图中的复选框双向绑定到我称为 State 的单独类中的布尔值 关键是要确保它们始终保持同步 因此 我在视图中创建了一个复选框 并将其绑定到前面提到的 State 类中的布尔属性 并附
  • winsock 在哪里存储套接字的 IP 地址?

    假设我有一个简单的 winsock 服务器 它有一个侦听套接字 然后当接受连接时 它将套接字存储在套接字数组中 以允许多个连接 如何获取特定连接的 IP 地址 它是否存储在套接字句柄中 只要套接字保持连接 您就可以获得自己的套接字地址和对等
  • 在 Java 中反序列化 C# 二进制

    我有一个系统 其中使用 C 程序创建序列化文件 然后在另一个 C 程序中反序列化 我想知道是否可以在 Java 中对 C 文件进行二进制反序列化 Thanks 您可以尝试使用一些具有两个平台实现并以与平台无关的格式输出数据的序列化器 例如
  • Angular 2:如何将 JavaScript 日期对象与 NgModel 两种方式绑定一起使用

    我正在使用 Angular 2 并且有以下代码 JS 此代码启动模板的员工变量 handleEmployee employee Employee this employee employee this employee startDate
  • 在 Windows 上使用 cmake 用于 C++

    连续大约 5 天 我一直在尝试使用 C 环境设置我的计算机 以便使用 sdl glm opengl 等库进行编程 能够在 UNIX 机器上的演示中运行它对我们来说很重要 所以我使用 cmake 运行 我终于让它与 cmake gui 一起工
  • 更改 WooCommerce“xyz”类别页面上显示的产品数量

    目前 我在 xyz 类别中有 19 个项目 但我一次只能看到其中 5 个 并且显示分页 但我不想分页 有没有办法让 5 个以上的项目显示在 xyz 类别的首页上 我将以下代码添加到模板的 function php 中 add filter
  • MySQL 控制台导入大型 SQL 文件时速度缓慢

    我通过 MySQL 控制台导入 SQL 的速度相当慢 而且随着我们的 SQL 文件每天都在增加 我想知道是否有其他方法可以更快地导入 SQL 文件 更改为 Oracle 或其他系统不是一个选择 配置必须保持不变 目前 SQL 文件大小为 1
  • android 游标到 JSONArray

    如何将 Cursor 转换 为 JSONArray 我的光标为 3 列 id 姓名 出生 我已经搜索过 但找不到任何示例 游标到 JSONArray public JSONArray cur2Json Cursor cursor JSONA
  • VirtualBox WordPress 重定向到端口 80

    我在 OSX 10 9 2 上运行 我刚刚在 VirtualBox 中的 Lubuntu 上设置了 LAMP 这样我就可以通过 VirtualBox 运行开发服务器 我改变了我的 etc apache2 ports conf监听 8080
  • Android Studio3.2 APK 构建错误 -> 保留文件或目录名称“lib”

    Android Studio 版本 3 2 AI 181 5540 7 32 5014246 在 Android Studio 3 1 中 我能够成功构建 SignedAPK 但当我制作了 Android Studio 3 2 后 我根本无
  • 添加回调 url 时 Twitter API oAuth 签名失败

    我正在使用这个代码 指南另一个失败的 Twitter oAuth cURL 访问令牌请求 https stackoverflow com questions 3295466 another twitter oauth curl access
  • .NET 转到 NuGet 包的实现

    有谁知道一种方法 工具可以让我浏览实施来自 NuGet 包的方法 类型 通过具有原始PDBs or a URL哪里可以得到它们 我知道来源链接 https github com dotnet core blob master Documen
  • 使用Flask return修改网页

    我有最简单的烧瓶应用程序 app Flask name app route python methods GET POST def index return Hello World if name main app run debug Tr
  • 从 thymeleaf spring 框架中的本地目录插入图像(使用 maven)

    我使用此链接开发了一个项目 https spring io guides gs serving web content https spring io guides gs serving web content 我使用maven来开发上述项
  • 使用参数作为列名的“排序依据”

    我们希望在使用 Visual Studio 数据集设计器创建的查询或存储过程的 Order By 子句中使用参数 Example FROM TableName WHERE Forename LIKE SearchValue OR Surna
  • MVVM 中的命令

    我看过一些教程 人们在他们的代码中创建像 CanExecute 这样的方法 我假设他们这样做是为了帮助读者理解这一切是如何运作的 当我查找 Command 和 ICommand 时 它会将我带到 MSDN 上用于 Windows 应用商店应
  • std::memory_order 和指令顺序,澄清

    这是一个后续问题this one https stackoverflow com questions 59626494 understanding memory order acquire and memory order release