- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我理解正确,在 C# 中,一个 lock
block 保证对一组指令的独占访问,但它也保证从内存中读取的任何内容都反射(reflect)了任何 CPU 缓存中该内存的最新版本.我们将 lock
block 视为保护 block 内读取和修改的变量,这意味着:
lock
block 中读取会看到变量的最新版本,在 lock
block 中写入对所有线程可见。(对吗?)
第二点是我感兴趣的。是否有一些魔法只有在受lock
block 保护的代码中读取和写入的变量才能保证新鲜,或者lock实现中使用的内存屏障
保证所有 内存现在对所有线程都同样新鲜?请原谅我对高速缓存如何工作的心理模糊,但我读到高速缓存包含几个多字节“行”的数据。我想我要问的是,内存屏障是否强制同步所有“脏”缓存行,或者只是一些,如果只是一些,是什么决定了同步哪些行?
最佳答案
If I understand correctly, in C#, a lock block guarantees exclusive access to a set of instructions...
没错。规范保证了这一点。
but it also guarantees that any reads from memory reflect the latest version of that memory in any CPU cache.
C# 规范对“CPU 缓存”只字未提。您已经离开了规范所保证的领域,进入了实现细节领域。不要求 C# 的实现在具有任何特定缓存架构的 CPU 上执行。
Is there some magic by which only variables read and written in code protected by the lock block are guaranteed fresh, or do the memory barriers employed in the implementation of lock guarantee that all memory is now equally fresh for all threads?
与其尝试解析您的非此即彼问题,不如说一下该语言实际保证的是什么。一个特殊的效果是:
在某些特殊点保留特殊效果的顺序:
运行时需要确保特效与特殊点的顺序一致。因此,如果在锁定之前读取了一个 volatile 字段,并在锁定之后写入,那么读取不能在写入之后移动。
那么,运行时是如何实现这一点的呢?打败了我。但是运行时肯定不需要“保证所有线程的所有内存都是新鲜的”。运行时需要确保某些读取、写入和抛出按时间顺序发生在特殊点上,仅此而已。
运行时特别不要求所有线程遵守相同的顺序。
最后,我总是通过将您指向此处来结束此类讨论:
http://blog.coverity.com/2014/03/26/reordering-optimizations/
读完之后,您应该了解即使在 x86 上当您随意删除锁时也可能发生的各种可怕事情。
关于c# - MemoryBarrier 是否保证所有内存的内存可见性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39602607/
VB.Net 没有等效的 C# volatile 关键字,因此您必须手动实现 volatile,这通常通过在读取之前和写入之后调用 Thread.MemoryBarrier() 来完成。所以这样的事情
using System; using System.Threading; using System.Threading.Tasks; class Program { static void
我修改了 Non-Blocking Synchronization 上给出的程序如下: class DemoProg { int _answer; bool _complete;
如果我理解正确,在 C# 中,一个 lock block 保证对一组指令的独占访问,但它也保证从内存中读取的任何内容都反射(reflect)了任何 CPU 缓存中该内存的最新版本.我们将 lock b
我需要一种可靠的方法来获得系统正常运行时间,并最终使用了如下方法。添加了一些评论以帮助人们阅读它。我不能使用任务,因为它必须在 .NET 3.5 应用程序上运行。 // This is a struc
由于似乎上下文切换可能发生在指令执行的任何时刻,所以我现在想知道为什么代码“部分有问题”(那两条指令)有意义,如果上下文切换可以在任何指令之间发生并且我们可能在不同的CPU上第二条指令的核心。 voi
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Why we need Thread.MemoryBarrier()? 摘自 O'Reilly 的 C# i
在 Java 中,我如何显式触发一个完整的内存栅栏/屏障,等于调用 System.Threading.Thread.MemoryBarrier(); 在 C# 中? 我知道,自从 Java 5 读取和
对于以下场景,使用MemoryBarrier在线程安全性、结果和性能方面是否有任何差异 private SomeType field; public SomeType Property { g
在这本线程在线书籍中:http://www.albahari.com/threading/part4.aspx 有一个 Thread.MemoryBarrier() 的例子 class Foo
这个网站的新手,所以如果我没有以可接受的方式发帖请告诉我。 我经常按照下面的示例编写代码(为清楚起见,省略了 Dispose 之类的内容。)。我的问题是,是否需要如图所示的 volatile ?或者
在“C# 4 in a Nutshell”中,作者展示了这个类有时可以在没有 MemoryBarrier 的情况下写入 0,尽管我无法在我的 Core2Duo 中重现: public class Fo
在 .NET 中 lock关键字是 Monitor.Enter 周围的语法糖和 Monitor.Exit ,所以你可以说这段代码 lock(locker) { // Do something }
下面的 GLSL 计算着色器简单地复制了 inImage至 outImage .它源自更复杂的后处理过程。 在main()的前几行,单个线程将 64 个像素的数据加载到共享数组中。然后,在同步之后,6
根据Web,我找到了如下代码,相当于C# Volatile for VB.NET。 代码引用:How do I specify the equivalent of volatile in VB.net
只是在业余时间玩并发性,并想尝试在不使用读取器端锁定的情况下防止撕裂读取,以便并发读取器不会相互干扰。 这个想法是通过锁序列化写入,但在读取端仅使用内存屏障。这是一个可重用的抽象,它封装了我提出的方法
通过浏览 MEF 源代码,我找到了这篇文章。有人可以解释为什么锁内需要 MemoryBarrier 吗? 整个方法是: public void SatisfyImportsOnce(Composabl
假设我有一个字段控制某个循环的执行: private static bool shouldRun = true; 我有一个正在运行的线程,其代码如下: while(shouldRun) { /
在 msdn 上 http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208(v=vs.85).aspx , MemoryBarr
如果我正确理解 volatile 和 MemoryBarrier 的含义,那么下面的程序将永远无法显示任何结果。 每次我运行它时,它都会捕获写入操作的重新排序。我在 Debug 或 Release 中
我是一名优秀的程序员,十分优秀!