我对有关 volatile
关键字与 System.Threading.Thread.VolatileRead
/VolatileWrite
和 System.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/VolatileWrite
和 System.Threading.Volatile.Read/Write
之间没有区别——它们是相同的辅助方法,它们在读取或写入之前模拟完整的内存屏障(不需要 MFENCE
指令)。这是内部实现:public static void VolatileWrite(ref sbyte address, sbyte value)
{
Thread.MemoryBarrier();
address = value;
}
volatile
变量在具有较弱内存模型的过时 IA 处理器架构 (Itanium) 上使用(-ed)获取/释放语义。 volatile
修饰符避免了编译器优化,也可以使用带有 lock
前缀的指令来保证一致性。 总而言之,编译器可能会使用各种技巧来遵守 C# memory model ,其中指出:
关于c# - c# 中的 volatile 字段实际上保证了什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59726742/