为什么方法调用会将非易失性变量的值刷新到主线程?

2023-12-27

为什么吸气剂Val碰巧模拟了该领域的波动性val?

我假设利用方法调用并不是保持变量易失性的可靠方法。

(要尝试一下,请构建发布并直接执行,无需调试器。)

class Program
{
    private int val = 0;
    public int Val { get { return val; } }

    public static void Main()
    {
        var example = new Program();

        Task.Run(() => example.val++);

        while (example.val == 0) ; // Hangs if val is not volatile
        while (example.Val == 0) ; // Never seems to hang
    }
}

好吧,原来允许抖动假设所有非易失性变量只能由一个线程访问 http://msdn.microsoft.com/en-us/library/x13ttww7.aspx(很像在 C++11 内存模型中,并发访问非std::atomic<>变量调用未定义的行为)。在这种情况下,抖动将第一个循环优化为loop: test eax, eax; je loop(它将变量访问提升到一个永远不会更新的寄存器中),所以显然它永远不会终止。

第二个循环生成读取相对于对象指针的值的程序集,因此最终它会看到新值(尽管相对于另一个线程上的其他写入可能是乱序的,同样是因为该变量不是易失性的)。这是由于碰巧生成的程序集而巧合的。

为第一个(无限)循环生成的 x86 程序集:

003B23BA  test        eax,eax  
003B23BC  je          003B23BA  

第二个(有限)循环的 x86 汇编:

002F2607  cmp         dword ptr [eax+4],0  
002F260B  je          002F2607

由于允许抖动假设非易失性变量永远不会被其他线程触及,你只能依靠volatile按预期工作(即使在给定的情况下,就像这样,因为未来的优化(或不同的 CPU 架构等)可能会以难以调试的方式破坏您的代码)。

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

为什么方法调用会将非易失性变量的值刷新到主线程? 的相关文章

随机推荐

  • JQuery mobile - 如何设置多重选择的值?

    我在 jquery mobile 中有一个多重选择 docs http jquerymobile com demos 1 0a4 1 docs forms forms selects html http jquerymobile com d
  • 对不平衡面板数据集进行子集化,以在 R 中至少有 2 个连续观测值

    我在 R 中有一个不平衡面板数据集 以下将作为示例 dt lt data frame name rep c A B C c 3 2 3 year c 2001 2003 2000 2002 2000 2001 2003 gt dt name
  • MATLAB eig 有时会返回倒号

    我正在尝试编写一个获取矩阵的程序A任何大小 SVD 分解它 A U S V Where A是用户输入的矩阵 U是由特征向量组成的正交矩阵A A S是奇异值的对角矩阵 并且V是特征向量的正交矩阵A A 问题是 MATLAB 函数eig有时会返
  • 访问shared_ptr数组

    include
  • 从文本文件中提取数据时出现问题

    我是 python 新手 我想从这种格式中提取数据 FBpp0143497 5 151 5 157 PF00339 22 Arrestin N Domain 1 135 149 83 4 1 1e 23 1 CL0135 FBpp01434
  • Javascript 获取表单数组值

    我设置了一个表单 其中有一个添加按钮 以便我的用户可以一次向该网站提交多人 首先 表单有一个输入来填写人员姓名 如下例所示
  • 计算每列中小于 x 的元素数量

    我有一个如下所示的数据框 我试图计算每列中小于 2 0 的元素数量 然后我将在条形图中可视化结果 我使用列表和循环来做到这一点 但我想知道是否有一种 熊猫方式 可以快速做到这一点 x for i in range 6 x append df
  • F# 使用累加器,仍然出现堆栈溢出异常

    在下面的函数中 我尝试通过使用累加器来设置尾递归 但是 我遇到了堆栈溢出异常 这让我相信我设置函数的方式没有正确启用尾递归 F attempting to make a tail recursive call via accumulator
  • 创建表达式树以访问通用类型的属性

    我需要编写一个泛型方法 它采用泛型类型的实例和字符串格式的属性名称 并返回一个表达式树 我需要转换一个简单的 lambda 表达式 a gt a SomePropertyName where a是泛型类型将拥有财产按名字SomeProper
  • “无法在此文件中预览 - 无法启动 [应用程序名称]”

    我正在尝试在 Xcode 11 和 macOS Catalina 中使用 swiftUI 但 创建新项目后 会出现一个样板代码 其中包含文本 hello World 我想在代码旁边的画布中实时预览这个简单的欢迎消息 当我点击恢复按钮时 它说
  • 优雅的蟒蛇? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • JS:不确定函数返回的原因

    确实是新手问题 但为什么我的函数返回 1 该函数确实有匹配项 那么为什么该函数返回 1 而不是索引值 如果我删除 else 语句 它将返回正确的输出 let array 1 2 3 4 5 6 7 8 9 let target 5 func
  • Powershell 在过去 6 个月内禁用 AD 用户?

    如何获取过去 6 个月内禁用的 AD 用户以及禁用时的时间戳 以 dd MM yyyy 格式作为 CSV 文件 就像使用这个 Powershellhttps learn microsoft com en us powershell modu
  • PHP 会话注销错误

    许多人可能会使用 PHP mySQL 函数作为网站的登录部分 我正在尝试使用这段代码 在每个内容页面上 检查是否已登录 在每个内容页面的标题中 Page Content Here 登录脚本 由我的 main login php 页面引用
  • 在 onDraw() 中保存画布;

    我试图将 Canvas 对象保存在 onDraw 方法中 这是因为我在 onDraw 方法中使用了 foreach 循环 结果是 canvas DrawText 文本项 x y textpaint 我必须这样做 因为我在遮罩区域周围绘制文本
  • Java 8 Streams 中的并行性和 Flatmap

    考虑以下示例 IntStream of 1 1 parallel flatMap i gt IntStream range 0 1000 parallel forEach System out println 我是否将内部标志设置为并行有关
  • C 语言的接口

    我正在设计一个应用程序并遇到一个实施问题 我有以下结构定义 app h struct application t void run application struct application t void stop application
  • 如何确定 ActiveRecord 中的关联是否发生变化?

    ActiveRecord 提供更改跟踪 其中调用 name changed 返回 true false 取决于是否name属性在模型加载时和现在之间发生了变化 协会有类似的东西吗 我专门寻找 has many 关联 但所有关联类型都会有用
  • 对于每种变量类型,将所有行除以一个参考行

    n c rep A 3 rep B 4 rep C 3 s 1 10 b 5 14 c 20 29 df data frame n s b c 我想要每个第一行 对于每种类型的变量n A B C 作为参考行 我想将每一行划分为每个类别n除以
  • 为什么方法调用会将非易失性变量的值刷新到主线程?

    为什么吸气剂Val碰巧模拟了该领域的波动性val 我假设利用方法调用并不是保持变量易失性的可靠方法 要尝试一下 请构建发布并直接执行 无需调试器 class Program private int val 0 public int Val