首先,我知道那lock{}
是Monitor
上课用的合成糖。(哦,语法糖)
我正在处理简单的多线程问题,发现无法完全理解如何锁定某些任意内存字来保护整个其他内存不被缓存是寄存器/CPU缓存等。使用代码示例来解释我在说什么更容易:
for (int i = 0; i < 100 * 1000 * 1000; ++i) {
ms_Sum += 1;
}
最终ms_Sum
将包含100000000
哪些,当然,这是预期的。
现在我们将在 2 个不同的线程上执行相同的循环,并且上限减半。
for (int i = 0; i < 50 * 1000 * 1000; ++i) {
ms_Sum += 1;
}
由于没有同步,我们得到了不正确的结果——在我的 4 核机器上,它几乎是随机数52 388 219
,略大于100 000 000
. 如果我们包含ms_Sum += 1;
在 中lock {}
,我们当然会得到绝对正确的结果100 000 000
。但是对我来说有趣的是(真的是说我期待类似的行为),添加lock
之前或之后的ms_Sum += 1;
行使答案几乎正确:
for (int i = 0; i < 50 * 1000 * 1000; ++i) {
lock (ms_Lock) {}; // Note curly brackets
ms_Sum += 1;
}
对于这种情况,我通常会得到ms_Sum = 99 999 920
,这是非常接近的。
问题:为什么确切地lock(ms_Lock) { ms_Counter += 1; }
使程序完全正确但lock(ms_Lock) {}; ms_Counter += 1;
几乎正确;锁定任意ms_Lock
变量如何使整个内存稳定?
非常感谢!
PS 去阅读有关多线程的书籍。
类似问题