繁体   English   中英

Threading.Volatile.Read(Int64) 和 Threading.Interlocked.Read(Int64) 的区别?

[英]Difference between Threading.Volatile.Read(Int64) and Threading.Interlocked.Read(Int64)?

.NET 系统类System.Threading.VolatileSystem.Threading.InterlockedRead(Int64)方法有什么区别(如果有)?

具体来说,关于(a)原子性和(b)内存排序,它们各自的保证/行为是什么。

请注意,这是关于Volatile类,而不是volatile (小写)关键字。


MS 文档状态:

Volatile.Read 方法

读取字段的值。 在需要它的系统上,插入一个内存屏障,以防止处理器重新排序内存操作,如下所示:如果在代码中此方法之后出现读取或写入,则处理器无法在此方法之前移动它。

...

返回Int64

读取的值。 该值是计算机中任何处理器写入的最新值,与处理器数量或处理器缓存状态无关。

对比

Interlocked.Read(Int64) 方法

返回一个 64 位值,作为原子操作加载。

特别令人困惑的是, Volatile文档没有谈论原子性,而Interlocked文档没有谈论排序/内存障碍。

旁注:作为参考:我更熟悉C++ 原子 API ,其中原子操作也总是指定内存排序语义。


Pavel提供的问题链接(和传递链接)很好地解释了 volatile-as-in-memory-barrier 和 atomic-as-in-no-torn-reads 的差异/正交性,但它们没有解释这两个概念如何应用于这两个类。

  • Volatile.Read是否对原子性做出任何保证?
  • Interlocked.Read (或者,实际上,任何Interlocked函数)是否对内存顺序做出任何保证?

Interlocked.Read 转换为 CompareExchange 操作

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

因此,它具有 CompareExchange 的所有优点:

  • 全内存屏障
  • 原子性

另一方面, Volatile.Read仅获取语义。 它可以帮助您确保读取操作的执行顺序,而无需任何原子性或新鲜度保证。

Volatile.Read(long)方法的文档没有提到任何关于原子性的内容,但源代码非常有启发性:

private struct VolatileIntPtr { public volatile IntPtr Value; }

[Intrinsic]
[NonVersionable]
public static long Read(ref long location) =>
#if TARGET_64BIT
    (long)Unsafe.As<long, VolatileIntPtr>(ref location).Value;
#else
    // On 32-bit machines, we use Interlocked, since an ordinary volatile read would not be atomic.
    Interlocked.CompareExchange(ref location, 0, 0);
#endif
  • 在 32 位机器上, Volatile.Read方法间接调用Interlocked.CompareExchange ,就像Interlocked.Read一样( 源代码),因此两者之间没有区别。 两种方法都会发出一个完整的栅栏。
  • 在 64 位机器上,读取的原子性由 CPU 架构保证,因此会发出更便宜的半栅栏。

所以Volatile.Read似乎是整体上更可取的选择。 尽管文档不保证它的原子性,但如果它不是原子的,它的有用性将受到严重限制(如果有的话)。 您对可能被破坏的价值有什么用处?

注意: Intrinsic属性意味着被修饰方法的代码可能被 Jitter 替换/优化。 这可能有点令人担忧,因此请自行判断在多线程环境中使用Volatile.Read读取long值是否安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM