Pie*_*kel 10 .net c# multithreading synchronization
我有一个小的测试应用程序,它同时执行两个线程.一个递增a static long _value
,另一个递减a.我已经确保ProcessThread.ProcessorAffinity
线程与不同的物理(无HT)内核相关联以强制进行内部处理器通信,并确保它们在执行时间内重叠了很长时间.
当然,以下不会导致零:
for (long i = 0; i < 10000000; i++)
{
_value += offset;
}
Run Code Online (Sandbox Code Playgroud)
因此,合乎逻辑的结论是:
for (long i = 0; i < 10000000; i++)
{
Interlocked.Add(ref _value, offset);
}
Run Code Online (Sandbox Code Playgroud)
这当然导致零.
但是,以下内容也会导致零:
for (long i = 0; i < 10000000; i++)
{
lock (_syncRoot)
{
_value += offset;
}
}
Run Code Online (Sandbox Code Playgroud)
当然,该lock
语句确保读取和写入不会重新排序,因为它使用了完整的栅栏.但是,我找不到任何有关处理器缓存同步的信息.如果没有任何缓存同步,我认为在两个线程完成后我应该看到偏离0?
有人可以向我解释如何lock
/ Monitor.Enter/Exit
确保处理器缓存(L1/L2缓存)是同步的吗?
在这种情况下,缓存一致性不依赖于lock
.如果使用lock
语句,则可确保汇编器命令不会混合.
a += b
它不是处理器的原子,它看起来像:
没有锁定它可能是:
但它不是关于缓存一致性,而是一个更高级别的功能.
因此,lock
不能确保缓存是同步的.缓存同步是处理器内部功能,不依赖于代码.你可以在这里阅读它.
当一个内核将值写入内存,然后当第二个内核尝试读取该值时,它将不会在其高速缓存中具有实际副本,除非其高速缓存条目无效,因此发生高速缓存未命中.并且此缓存未命中强制缓存条目将更新为实际值.