gpt4 book ai didi

c# - 这是对 Thread.MemoryBarrier() 的正确使用吗?

转载 作者:IT王子 更新时间:2023-10-29 04:41:44 25 4
gpt4 key购买 nike

假设我有一个字段控制某个循环的执行:

private static bool shouldRun = true;

我有一个正在运行的线程,其代码如下:

while(shouldRun) 
{
// Do some work ....
Thread.MemoryBarrier();
}

现在,另一个线程可能会将 shouldRun 设置为 false,而不使用任何同步机制。

据我了解 Thread.MemoryBarrier(),在 while 循环中进行此调用将阻止我的工作线程获取 shouldRun 的缓存版本,并有效地防止无限循环的发生.

我对 Thread.MemoryBarrier 的理解是否正确?鉴于我有可以设置 shouldRun 变量的线程(这不容易更改),这是合理的吗确保一旦 shouldRun 被任何线程设置为 false 我的循环将停止的方法?

最佳答案

Is this a correct use of Thread.MemoryBarrier()?

没有。假设一个线程在循环开始执行之前设置标志。循环仍然可以执行一次,使用标志的缓存值。那是正确的吗?这对我来说当然是不正确的。我希望如果我在第一次执行循环之前设置标志,则循环执行零次,而不是一次。

As far as I understand Thread.MemoryBarrier(), having this call inside the while loop will prevent my work thread from getting a cached version of the shouldRun, and effectively preventing an infinite loop from happening. Is my understanding about Thread.MemoryBarrier correct?

内存屏障将确保处理器不会对读取和写入进行任何重新排序,这样逻辑上屏障之前的内存访问实际上被观察到它之后,反之亦然。

如果您一心想编写低锁代码,我倾向于使该字段可变,而不是引入显式内存屏障。 “volatile” C# 语言的一个特性。一个危险且鲜为人知的特性,但却是语言的一个特性。它清楚地告诉代码的读者,所讨论的字段将在多线程上无锁地使用。

is this a reasonable way to ensure that my loop will stop once shouldRun is set to false by any thread?

有些人会认为这是合理的。如果没有非常非常好的理由,我不会在自己的代码中这样做。

通常,低锁技术是出于性能考虑而合理的。有两个这样的考虑因素:

首先,争用锁可能非常慢;只要锁中有代码在执行,它就会阻塞。如果因为争用太多而出现性能问题,那么我会首先尝试通过消除争用来解决问题。只有当我无法消除争用时,我才会采用低锁技术。

其次,无竞争 锁可能太慢了。如果您在循环中执行的“工作”花费的时间少于 200 纳秒,那么检查无竞争锁所需的时间(大约 20 ns)是工作时间的很大一部分。在这种情况下,我建议您在每个循环中做更多的工作。真的有必要在设置控制标志后的 200 ns 内停止循环吗?

只有在最极端的性能场景下,我才会认为检查非竞争锁的成本占程序时间的很大一部分。

当然,如果您每 200 ns 左右引入一次内存屏障,您也可能以其他方式破坏性能。处理器想要为您进行那些移动内存访问的实时优化;如果您强制它不断放弃这些优化,您就会错失潜在的胜利机会。

关于c# - 这是对 Thread.MemoryBarrier() 的正确使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8729466/

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