gpt4 book ai didi

c# - 此 C# 代码是否会因为寄存器或缓存中的值永远不会写回主内存而失败?

转载 作者:太空狗 更新时间:2023-10-30 00:52:10 25 4
gpt4 key购买 nike

在本文中:

http://msdn.microsoft.com/en-us/magazine/jj883956.aspx

作者声明以下代码可能由于“循环读取提升”而失败:

class Test
{
private bool _flag = true;
public void Run()
{
// Set _flag to false on another thread
new Thread(() => { _flag = false; }).Start();
// Poll the _flag field until it is set to false
while (_flag) ;
// The loop might never terminate!
}
}

在循环读取提升中,由于单线程假设,编译器可能会将上面的 while 循环更改为以下内容:

if (_flag) { while (true); }

我想知道的是:如果编译器执行该优化,那么由于一个处理器在注册或缓存并且从不将该缓存刷新回另一个线程可读的内存?我读过“C# 写入是易变的”,但我链接到的文章说这实际上并没有得到 ECMA 规范的保证,而且在 ARM 上也没有以这种方式实现。我试图弄清楚我必须多么偏执才能编写适用于所有平台的线程代码。

这是一个相关的问题:

Can a C# thread really cache a value and ignore changes to that value on other threads?

但我认为已接受答案中的代码可能已通过循环读取提升进行了优化,因此它无法证明内存可见性......

最佳答案

if the compiler doesn't perform that optimization, is there still potential for the loop to run forever on a multiprocessor machine due to one processor updating _flag in a register or cache and never flushing that cache back to memory readable by the other thread?

是的。

I've read that "C# writes are volatile," but the article I linked to says this is not actually guaranteed by the ECMA spec and things aren't implemented that way on ARM.

这有什么关系?主线程不是在写,而是在读。

I'm trying to figure out how paranoid I have to be to write threaded code that will work on all platforms.

如果他们真的想抓你,那不是偏执狂。线程很难。做我做的事:将共享内存的低级操作留给专家。

使用尽可能高的抽象级别编写您的代码,并由专家为您编写抽象。您几乎不应该按照您描述的那样编写代码,不是因为它是错误的——尽管它是错误的——而是因为它处于错误的抽象级别。如果您想表示“可以取消此操作”的想法,请使用 CancellationToken ;这就是他们的目的。如果你想表示“这项工作在未来产生结果”的概念,请使用 Task<T> ;这就是他们的目的。不要尝试自己动手;让 Microsoft 为您完成。

更新:有关 C# 中的线程安全、可变语义、低锁技术以及为什么应该避免自己做所有这些事情的更多信息,请参阅:

万斯 2005 年关于低锁技术的精彩文章:

http://msdn.microsoft.com/en-us/magazine/cc163715.aspx

我的 2011 系列三篇文章从这里开始:

http://ericlippert.com/2011/05/26/atomicity-volatility-and-immutability-are-different-part-one/

特别是第三个与您相关,但前两个也可能很有趣。

Joe Duffy 重申了为什么不应该使用 volatile:

http://joeduffyblog.com/2010/12/04/sayonara-volatile/

我 2014 年的两篇 Ask The Bug Guys 文章:

http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/ http://blog.coverity.com/2014/03/26/reordering-optimizations/

我已经按照合理的阅读顺序给出了这些内容;如果您觉得 Vance 的文章太难阅读,请尝试从我的三部分系列文章开始,然后再返回。

关于c# - 此 C# 代码是否会因为寄存器或缓存中的值永远不会写回主内存而失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23110762/

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