这是一个简单的问题,但是读完之后为什么需要内存屏障? https://stackoverflow.com/questions/3493931/why-do-i-need-a-memory-barrier我对此很困惑。
在下面的示例中,假设不同的线程重复调用 Increment 和 Counter:
class Foo{
int _counter=0;
public int Counter
{
get { return _counter; }
}
public void Increment()
{
Interlocked.Increment(ref _counter);
}
}
抱歉,如果我误解了为什么需要内存屏障? https://stackoverflow.com/questions/3493931/why-do-i-need-a-memory-barrier但似乎表明上面的课程可能没有提供新鲜保证当读取_counter的值时。重复访问 Counter 属性的线程是否会永远卡在 Counter 的旧值上(因为它缓存在寄存器中)?
之前是内存屏障还是锁return _counter;
必要的?
return_counter之前是内存屏障还是锁;必要的?
是的,一点没错。考虑以下代码。
while (foo.Counter == 0)
{
// Do something
}
问题是,如果循环内的内容足够简单,那么 C# 编译器、JIT 编译器或硬件将以这种方式优化代码。
int register = foo._counter;
while (register == 0)
{
// Do something
}
甚至这个。
if (foo._counter == 0)
{
START:
// Do something
goto START;
}
请注意,我使用_counter
代替Counter
作为暗示该属性可能会被内联的一种方式。然后,更重要的是,JIT 编译器可能会“提升”对_counter
在循环之外,以便只读取一次。
内存屏障不提供新鲜保证本身。它们的作用是阻止某些重新排序内存读写的软件或硬件优化。这新鲜保证确实更多的是副作用。
所以要结束你的事情Counter
财产应该是这样的。
public int Counter
{
get { return Interlocked.CompareExchange(ref _counter, 0, 0); }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)