gpt4 book ai didi

c# - 并发互锁和读取是否需要内存屏障或锁定?

转载 作者:行者123 更新时间:2023-11-30 14:15:34 25 4
gpt4 key购买 nike

这是一道简单的题,但是看完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);
}
}

抱歉,如果我误解了 Why do I need a memory barrier?但它似乎暗示上面的类在读取 _counter 的值时可能不提供新鲜度保证。重复访问 Counter 属性的线程是否会永远停留在 Counter 的旧值上(因为它缓存在寄存器中)?

return _counter; 之前是否需要内存屏障或锁?

最佳答案

Is a memory barrier or a lock before return _counter; necessary?

是的,绝对是。考虑以下代码。

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); }
}

关于c# - 并发互锁和读取是否需要内存屏障或锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9834556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com