gpt4 book ai didi

c# - 我什么时候可以保证一个线程上更改的值对其他线程可见?

转载 作者:太空宇宙 更新时间:2023-11-03 12:44:20 25 4
gpt4 key购买 nike

我知道一个线程可以缓存一个值和ignore changes made on another thread ,但我想知道这个的变体。线程是否有可能更改缓存的值,然后该值永远不会离开其缓存,因此对其他线程永远不可见?

例如,此代码是否可以打印“Flag is true”,因为线程a 永远不会看到线程b 所做的更改>标志? (我无法让它这样做,但我无法证明它或它的某些变体不会。)

var flag = true;
var a = new Thread(() => {
Thread.Sleep(200);
Console.WriteLine($"Flag is {flag}");
});
var b = new Thread(() => {
flag = false;
while (true) {
// Do something to avoid a memory barrier
}
});

a.Start();
b.Start();

a.Join();

我可以想象在线程 bflag 可以缓存在 CPU 寄存器中,然后将其设置为 false,并且当 b 进入 while 循环,它从来没有机会(或从不关心)将 flag 的值写回内存,因此 a 始终将 flag 视为 true。

来自 this answer 中列出的内存屏障生成器在我看来,这在理论上是可能的。我对么?我无法在实践中证明这一点。任何人都可以想出一个例子吗?

最佳答案

Is it possible for a thread to change a cached value, which then never leaves its cache and so is never visible to other threads?

如果我们从字面上谈论硬件缓存,那么我们需要讨论特定的处理器系列。如果您在 x86(和 x64)上工作(看起来很可能),您需要知道这些处理器实际上具有比 .NET 所需的内存模型强得多的内存模型。在 x86 系统中,缓存保持一致性,因此其他处理器不会忽略任何写入。

如果我们谈论优化,其中一个特定的内存位置已被读入处理器寄存器,然后从内存中读取的后续只是重用该寄存器,那么就没有类似的模拟在写入端。您会注意到,在我们假设没有其他任何东西改变该内存位置之前,总是有至少一个从实际内存位置读取,因此我们可以重用该寄存器。

在写入方面,我们被告知要将某些内容推送到特定的内存位置。我们必须至少推送到该位置一次,并且始终将先前已知的值存储在该位置(特别是如果我们的线程从未从中读取)在一个单独的寄存器中只是为了能够执行比较可能是一种去优化并省略写操作。

关于c# - 我什么时候可以保证一个线程上更改的值对其他线程可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37879659/

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