我对有关 volatile 关键字与 System.Threading.Thread.VolatileRead/VolatileWriteSystem.Threading.Volatile.Read/Write 的 .NET/C# 文档感到困惑。我试图了解 volatile 字段的确切保证以及这些方法究竟在做什么。

我以为 volatile 提供了发布/获取语义,但是 Thread.VolatileRead/VolatileWrite 的文档让我怀疑我的理解是否真的正确。

这是 volatile 的语言引用:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/volatile



到目前为止是有道理的。这是语言规范:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#volatile-fields



同样,这看起来像 volatile 提供了发布/获取语义。

但后来我查看了 Thread.VolatileRead 的文档:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.volatileread?view=netframework-4.8#System_Threading_Thread_VolatileRead_System_Int64__



对于 Thread.VolatileWrite:



这看起来比单独的存储/加载栅栏(释放/获取)更严格,特别是关于刷新处理器缓存的部分,即比 volatile 更严格的保证。但随后同一份文件说:



所以我的问题是 - volatile 字段对于存储缓冲区的保证是什么 - 只是释放/获取,还是更强的 Thread.VolatileRead/Write 保证?或者我对 VolatileRead/Write 的理解是错误的,这些与 volatile 相同?

最佳答案

  • System.Threading.Thread.VolatileRead/VolatileWriteSystem.Threading.Volatile.Read/Write 之间没有区别——它们是相同的辅助方法,它们在读取或写入之前模拟完整的内存屏障(不需要 MFENCE 指令)。这是内部实现:

  • public static void VolatileWrite(ref sbyte address, sbyte value)
    {
      Thread.MemoryBarrier();
      address = value;
    }
    
  • volatile 变量在具有较弱内存模型的过时 IA 处理器架构 (Itanium) 上使用(-ed)获取/释放语义。
  • 在最流行的 x86 架构中,volatile 修饰符避免了编译器优化,也可以使用带有 lock 前缀的指令来保证一致性。

  • 总而言之,编译器可能会使用各种技巧来遵守 C# memory model ,其中指出:

    关于c# - c# 中的 volatile 字段实际上保证了什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59726742/

    10-12 03:25