【发布时间】:2011-08-25 04:18:20
【问题描述】:
我有一个同时执行两个线程的小型测试应用程序。一个增加static long _value,另一个减少它。我已通过 ProcessThread.ProcessorAffinity 确保线程与不同的物理(无 HT)内核相关联以强制处理器内部通信,并且我已确保它们在执行时间上重叠很长时间。
当然,以下不会导致零:
for (long i = 0; i < 10000000; i++)
{
_value += offset;
}
因此,合乎逻辑的结论是:
for (long i = 0; i < 10000000; i++)
{
Interlocked.Add(ref _value, offset);
}
这当然会导致零。
但是,以下也导致零:
for (long i = 0; i < 10000000; i++)
{
lock (_syncRoot)
{
_value += offset;
}
}
当然,lock 语句确保读取和写入不会重新排序,因为它使用了完整的栅栏。但是,我找不到有关处理器缓存同步的任何信息。如果没有任何缓存同步,我想我应该在两个线程完成后看到与 0 的偏差?
谁能向我解释一下lock/Monitor.Enter/Exit 如何确保处理器缓存(L1/L2 缓存)同步?
【问题讨论】:
-
“我已确保它们同时开始”。不完全是,您无法控制操作系统相对于其他应用程序如何调度您的应用程序的线程。但在大多数情况下,这无关紧要。
-
抱歉,表述错误。我已确保它们大致在同一时间开始,并且我已确保它们在执行时间上重叠。更新了问题。感谢您的观察。
标签: c# .net multithreading synchronization