锁定是否确保从缓存中刷新读取和写入? 如果是这样,怎么样?

我正在阅读这篇关于无锁线程同步的MSDN文章 。 这篇文章似乎推断,只要你在访问共享变量之前输入一个锁,那么这些变量将是最新的(至少在.Net 2.0中)。

我想到这是怎么可能的? .Net中的锁只是所有线程在访问内存之前检查的任意对象,但锁本身并不知道正在访问的内存位置。

如果我有一个线程更新变量,甚至整个内存块,那么当进入/退出锁时,这些更新如何保证从CPU缓存刷新? 所有内存访问是否在锁内有效地变为易失性?

检查Eric Lippert的工作: http : //blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx

锁定保证锁内部读取或修改的内存是一致的,锁定保证一次只有一个线程访问给定的内存块,依此类推。

所以,是的,只要您在访问共享资源之前每次都锁定,您就可以非常确定它是最新的

编辑查看以下文章以获取更多信息和非常有用的概述: http : //igoro.com/archive/volatile-keyword-in-c-memory-model-explained/

好吧,文章解释说:

  1. 在进入锁定之前,读取不能移动。

  2. 退出锁定后写入无法移动。

来自同一篇文章的更多解释:

当线程退出锁定时,第三个规则确保在保持锁定时进行的任何写入对所有处理器都是可见的。 在另一个线程访问内存之前,读取线程将进入锁定,第二个规则确保在执行锁定后逻辑上发生读取。

并非所有c#内存读写都是易失性的,不是。 (想象一下,如果情况表现如此!)

但。

在进入/退出锁定时,如何保证从CPU缓存中刷新这些更新

CPU缓存是CPU特定的,但它们都具有某种forms的内存一致性协议 。 也就是说,当您从核心访问某些内存时,如果它存在于另一个核心缓存中,则CPU使用的协议将确保将数据传递到本地核心。

然而,Petar Ivanov在他的回答中暗示的是非常相关的。 如果您想了解更多他的观点,您应该查看内存一致性模型 。

现在,C#如何保证内存是最新的取决于C#实现者,而Eric Lippert的博客肯定是理解潜在问题的好地方。

我不确定.NET中的事态,但在Java中明确指出,以这种方式合作的任何两个线程必须使用相同的对象进行锁定,以便从您在介绍性声明中所说的内容中受益,不只是锁定。 这是一个至关重要的区别。

锁不需要“知道”它所保护的内容; 它只需要确保前一个储物柜写的所有东西都可以在另一个储物柜继续使用之前使用。