Monitor.Wait 是否确保重新读取字段?

2023-12-25

人们普遍接受(我相信!)lock将强制重新加载字段中的任何值(本质上充当内存屏障或栅栏 - 恐怕我在这方面的术语有点宽松),其结果是字段仅ever在 a 内访问lock自己不需要volatile.

(如果我已经错了,请说出来!)

一个很好的评论是在这里长大 https://stackoverflow.com/questions/2430609/c-is-it-possible-to-interrupt-a-specific-thread-inside-a-threadpool/2430684#2430684,质疑如果代码执行以下操作是否同样成立Wait()- 即一旦它已经Pulse()d,它是否会从内存中重新加载字段,或者它们可能位于寄存器中(等等)。

或者更简单地说:该字段是否需要volatile确保在恢复后获得当前值Wait()?

看着反光镜,Wait向下调用ObjWait,即managed internalcall(与Enter).

所讨论的场景是:

bool closing;
public bool TryDequeue(out T value) {
    lock (queue) { // arbitrary lock-object (a private readonly ref-type)
        while (queue.Count == 0) {
            if (closing) {       // <==== (2) access field here
                value = default(T);
                return false;
            }
            Monitor.Wait(queue); // <==== (1) waits here
        }
        ...blah do something with the head of the queue
    }
}

显然我可以做到volatile,或者我可以将其移出,以便我退出并重新进入Monitor每次它发出脉冲时,但我很想知道是否是必要的.


自从Wait()方法是释放并重新获取Monitor锁定,如果lock执行内存栅栏语义,然后Monitor.Wait()也会的。

希望能解决您的评论:

的锁定行为Monitor.Wait()在文档中(http://msdn.microsoft.com/en-us/library/aa332339.aspx http://msdn.microsoft.com/en-us/library/aa332339.aspx),强调补充:

当线程调用Wait时,它会释放对象上的锁并进入对象的等待队列。对象就绪队列中的下一个线程(如果有的话)获取锁并独占使用该对象。所有调用的线程Wait保留在等待队列中,直到收到来自 Pulse 的信号或PulseAll,由锁的所有者发送。如果Pulse发送后,只有位于等待队列头部的线程受到影响。如果PulseAll发送后,所有正在等待该对象的线程都会受到影响。当接收到信号时,一个或多个线程离开等待队列并进入就绪队列。允许就绪队列中的线程重新获取锁。

当调用线程重新获取对象上的锁时,此方法返回.

如果您询问是否有参考资料lock/获得Monitor意味着内存障碍,ECMA CLI 规范 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf说如下:

12.6.5 锁和线程:

获取锁(System.Threading.Monitor.Enter或进入同步方法)应隐式执行易失性读操作,并释放锁(System.Threading.Monitor.Exit或离开同步方法)应隐式执行易失性写入操作。参见第 12.6.7 节。

12.6.7 易失性读和写:

易失性读取具有“获取语义”,这意味着读取保证发生在 CIL 指令序列中读取指令之后发生的对内存的任何引用之前。易失性写入具有“释放语义”,这意味着写入保证发生在 CIL 指令序列中写入指令之前的任何内存引用之后。

此外,这些博客文章还有一些可能令人感兴趣的细节:

  • http://blogs.msdn.com/jaredpar/archive/2008/01/17/clr-memory-model.aspx http://blogs.msdn.com/jaredpar/archive/2008/01/17/clr-memory-model.aspx
  • http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/ http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/
  • http://www.bluebytesoftware.com/blog/2007/11/10/CLR20MemoryModel.aspx http://www.bluebytesoftware.com/blog/2007/11/10/CLR20MemoryModel.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Monitor.Wait 是否确保重新读取字段? 的相关文章

随机推荐

  • 如何给java足够的时间给变量赋值? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我有一个循环 在循环的末尾有一个String 被添加到ArrayList 在类中声明而不是方法 并在循环开始时说Stri
  • 如何发出数据流已完成的信号?

    我有一个类 它使用 TPL 数据流实现由 3 个步骤组成的数据流 在构造函数中 我将步骤创建为 TransformBlocks 并使用 LinkTo 将它们链接起来 并将 DataflowLinkOptions PropagateCompl
  • 在 PHP 7.4 中使用 FFI 加载库时出现问题

    我在新的 FFI 中使用 PHP 中的第三方 so 库时遇到问题 当我运行这段小代码时
  • 如何获取asp.net下拉列表的选定值并将其存储在会话变量中?

    Dim ename As String DropDownList SelectedItem Value 这个声明不起作用 任何帮助表示赞赏 我不确定这是否是您的问题 但如果您正在寻找所需的项目文本 而不是值 DropDownList Sel
  • 使用 Jquery 从第一个下拉列表中过滤第二个下拉列表

    Team 我有两个下拉菜单说 年 和 节 1 年份下拉菜单将有以下选项 显示全部 1 2 3 4 2 部分下拉菜单将有以下选项 所有部分 1 部分 A 1 部分 B 1 部分 C 2 部分 A 2 部分 B 3 部分 A 4 部分 A 4
  • 强制用户在 iOS 中以编程方式更新应用程序

    在我的 iOS 应用程序中 我启用了强制应用程序更新功能 是这样的 如果有严重的错误修复 在服务器中我们正在设置新的发行版本 在启动屏幕中 我正在检查当前的应用程序版本 如果它低于服务版本 则会显示一条更新应用程序的消息 我放置了 2 个按
  • Spring RestTemplate - 需要释放连接吗?

    这是我的 Rest 模板配置 Bean Qualifier myRestService public RestTemplate createRestTemplate Value connection timeout String maxCo
  • 为什么不可能构建一个可以确定 C++ 函数是否会更改特定变量值的编译器?

    我在一本书上读到这样一句话 事实证明 构建一个可以实际执行的编译器是不可能的 确定 C 函数是否会更改 a 的值 特定变量 该段落讨论了为什么编译器在检查常量性时是保守的 为什么不可能构建这样的编译器 编译器始终可以检查变量是否被重新分配
  • 使用java从cassandra读取数据

    My sample cassandra table looks like id article read last hours name 5 4 5 6 5 shashank 10 12 88 32 1 sam 8 4 5 6 8 aman
  • 更改 Chart.js 工具提示中的日期格式

    我正在使用 Chart js 生成图表 一切正常 但是如何格式化工具提示信息呢 应该是 2020年4月28日 05 00 你需要定义time tooltipFormat https www chartjs org docs latest a
  • 如何从 NSArray 中的每个 NSDictionary 获取特定键的所有值? [复制]

    这个问题在这里已经有答案了 我有一个包含字典对象的数组 每个字典中的键都是通用的 现在我想获取该键的所有值 我已经通过迭代获得了这些值 但我正在寻找一些直接的方法或完成这项工作的默认方法 您能帮助我获得一种可以达到目的的默认方法吗 谢谢 数
  • 跨浏览器另存为.txt

    是否有一个 JavaScript 库允许将字符串保存为 txt 文件 并且可以跨浏览器工作 过去 我一直在使用 Downloadify 但出于以下几个原因 我正在考虑另一个选择 我希望找到一个纯JavaScript的解决方案 而不需要Fla
  • 获取 2 个日期之间的所有月份

    我创建了一个函数 它返回一个包含每个月的数组 从提供的碳日期开始到当前日期结束 虽然这个函数正在做它应该做的事情 但它看起来很丑陋 显然我的编程技能还没有达到应有的水平 当然必须有更好的方法来实现我想要的 我的代码如下所示 class Da
  • Python 请求,无文件的多部分

    是否可以使用 python 请求发送多部分 表单数据而不发送文件 我的请求标头应如下所示 3eeaadbfda0441b8be821bbed2962e4d Content Disposition form data name value c
  • 角度单元测试:如何在没有范围的情况下测试控制器属性

    我正在尝试为控制器编写一些测试 但是所有文档 教程 等都演示了 scope 上的函数和变量 如果你想测试不在 scope 上的东西怎么办 Ex app controller fakeCtrl function scope var foo b
  • 是否可以对 HashMap 的键和值使用单个泛型?

    In Rust 书第 13 章 https doc rust lang org book second edition ch13 01 closures html 你实现了一个Cacher使用记忆来演示函数式编程以及如何加速长时间运行的任务
  • 当 --module 为“none”时,如何使用 @types npm 存储库中的 TypeScript 定义文件

    如果编译器的模块系统参数设置为 none 如何通过 types 使用 TypeScript 定义文件 例如 当使用 Express Web 服务器的类型定义时 npm 安装 types express 使用以下 tsconfig json
  • UIView - 加载视图时如何收到通知?

    有没有类似的东西viewDidLoad of UIViewController for a UIView 我需要尽快收到通知UIView已加载 子类UIView 并执行一些操作 根据您需要执行的操作类型 有几种技术 id initWithF
  • Gmail 类似 URL 方案

    我正在开发票务系统 有以下要求 主页分为两个部分 第 1 节 此处显示了一些过滤器选项 例如封闭票证 开放票证 所有票证 分配给我的票证等 您可以选择一个或多个这些过滤器 第 2 节 此处将显示满足上述筛选条件的门票列表 现在这就是我想要的
  • Monitor.Wait 是否确保重新读取字段?

    人们普遍接受 我相信 lock将强制重新加载字段中的任何值 本质上充当内存屏障或栅栏 恐怕我在这方面的术语有点宽松 其结果是字段仅ever在 a 内访问lock自己不需要volatile 如果我已经错了 请说出来 一个很好的评论是在这里长大