锁定是否确保读取和写入从缓存中刷新?如果有,怎么做呢?
本文关键字:如果 刷新 读取 确保 是否 缓存 锁定 | 更新日期: 2023-09-27 18:11:42
我正在阅读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
锁保证在锁内读取或修改的内存是一致的,锁保证一次只有一个线程访问给定的内存块,等等。
所以是的,只要你在访问共享资源之前每次都锁定,你就可以非常确定它是最新的
EDIT查看以下文章以获取更多信息和非常有用的概述:http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
文章对此作了解释:
read在进入锁之前不能移动
写操作退出锁后不能移动
和来自同一篇文章的更多解释:
当线程退出锁时,第三条规则确保在持有锁期间进行的任何写操作对所有处理器都是可见的。在另一个线程访问内存之前,读取线程将进入一个锁,第二条规则确保读取在锁被获取后逻辑地发生。
不是所有的c#内存读写都是易失的,不是的。(想象一下,如果这是性能方面的情况!)
。
当进入/退出锁时,如何保证这些更新从CPU缓存中刷新
CPU缓存是特定于CPU的,但是它们都有某种形式的内存一致性协议。也就是说,当你从一个核心访问一些内存时,如果它存在于另一个核心缓存中,CPU使用的协议将确保数据被传递到本地核心。
然而,Petar Ivanov在他的回答中暗示的是非常相关的。如果您想了解更多他的观点,您应该查看内存一致性模型。现在,c#如何保证内存是最新的取决于c#实现者,Eric Lippert的博客当然是理解潜在问题的好地方。
我不确定。net中的情况,但是在Java中明确规定,任何两个以这种方式合作的线程都必须使用相同的对象进行锁定,以便从您在介绍语句中所说的受益,而不仅仅是任何锁。这是一个至关重要的区别。
锁不需要"知道"它保护的是什么;它只需要确保前一个locker所写的所有内容都可以被另一个locker使用,然后再让它继续。