为什么 Interlocked.Read 在内部使用 Interlocked.CompareExchange?

Why Interlocked.Read uses Interlocked.CompareExchange internally?

提问人:user22155685 提问时间:11/17/2023 最后编辑:Theodor Zouliasuser22155685 更新时间:11/17/2023 访问量:50

问:

以下是我对 Interlocked 的评论的源代码:

public static class Interlocked {

   // Int32 old = location;
   // if (location == comparand) location = value;
   // return old; 
   public static Int32 CompareExchange(ref Int32 location, Int32 value, Int32 comparand);

   public static long Read(ref long location)
   {
      return Interlocked.CompareExchange(ref location, 0, 0);
   }

}

我不明白为什么读电话?Interlocked.CompareExchange(ref location, 0, 0)

long location可以是任何数字,为什么与0进行比较?

C# .NET CLR 联锁

评论

0赞 Etienne de Martel 11/17/2023
你知道有什么作用吗?因为我认为从那里开始会有所帮助。CompareExchange
0赞 user22155685 11/17/2023
是的,我知道有什么作用,但我不知道为什么需要。我的意思是为什么读取一个值会导致它被更改为 0?CompareExchangeCompareExchange
0赞 Etienne de Martel 11/17/2023
所以你不知道它有什么作用。 仅当值等于 comparand 时才写入 location。因此,如果它已经是 0,它只会写入 0,这意味着没有实际的变化。CompareExchange

答:

1赞 dropoutcoder 11/17/2023 #1

使用该方法的主要原因是确保在 32 位系统上读取 64 位值是原子值。默认情况下,在 64 位系统上读取 64 位值是原子值。Interlocked.CompareExchange()

这也是为什么方法只接受 和 参数。Interlocked.Read()Uint64Int64

Interlocked.CompareExchange()method 是原子操作,它将存储在 with 参数中的原始值进行比较,以确保我们想要交换的值不会被访问该变量的其他线程更改。如果该值未更改,则将其替换,否则不会发生任何反应,但始终返回存储在 中的原始值。location1comparandlocation1

因此,实际利用上面编写的方法,通过尝试将 0 与存储在其中的值进行比较,并基于该比较替换值或不替换值,但返回原始值。Read()location1

这可以翻译成类似的东西

if(original == comparand) {
    return original;
} else {
    var temp = original;
    original = value;
    return temp;
}

这就是为什么方法在内部使用方法的原因,因为任何时候你都会使用,你会得到原始值,如果你传递相同的值,你永远不会进入这种情况,交换就会发生。要么值不同,交换根本不会发生,要么值相同,交换即将发生,但您正在将 0 换成 0。Read()CompareExchange()CompareExchange()valuecomparand

评论

0赞 user22155685 11/17/2023
对不起,还是一头雾水,那不是原子的,所以加载操作不会中断吗?另外,读取是加载操作,为什么会涉及存储操作?Interlocked.Readoriginal = value;
0赞 dropoutcoder 11/17/2023
Interlocked.Read是原子操作,但在 32 位系统上不是。这就是为什么只为 64 位数值类型引入的原因,而不是任何其他类型,因为默认情况下,这些数值类型在 32 位和 64 位上是原子的。long temp = original;ulong temp = original;Interlocked.Read
0赞 dropoutcoder 11/17/2023
为什么要有店铺运营?我想说的是,这只是在 32 位系统上读取 64 位值的特定情况的解决方法。
0赞 dropoutcoder 11/17/2023
为什么有?这就是工作方式。我的例子只是为了解释决定在内部使用它背后的逻辑。original = value;Interlocked.CompareExchange
0赞 dropoutcoder 11/17/2023
支持 .NET Framework 1.0 和 1.1,并且很可能在设计时只考虑了 32 位系统。下一个主要版本 .NET Framework 2.0 添加了对 64 位系统的完全支持。随之而来的是需要解决的挑战。 class 是在 1.1 版中引入的。 在 2.0 版中引入了这些挑战。InterlockedInterlocked.Read