我对有关 volatile
的 .NET/C# 文档感到困惑关键字 vs System.Threading.Thread.VolatileRead
/VolatileWrite
和 System.Threading.Volatile.Read/Write
.我试图了解 volatile 字段的确切保证以及这些方法究竟在做什么。
我以为volatile
提供发布/获取语义,但提供 Thread.VolatileRead
的文档/VolatileWrite
让我怀疑我的理解是否真的正确。
这是 volatile 的语言引用:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/volatile
Adding the volatile modifier ensures that all threads will observe volatile writes performed by any other thread in the order in which they were performed. There is no guarantee of a single total ordering of volatile writes as seen from all threads of execution.
到目前为止是有道理的。这是语言规范:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#volatile-fields
For volatile fields, such reordering optimizations are restricted:
A read of a volatile field is called a volatile read. A volatile read has "acquire semantics"; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence. A write of a volatile field is called a volatile write. A volatile write has "release semantics"; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.
These restrictions ensure that all threads will observe volatile writes performed by any other thread in the order in which they were performed. A conforming implementation is not required to provide a single total ordering of volatile writes as seen from all threads of execution.
同样,这看起来像
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__
Reads the value of a field. The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache. ... On a multiprocessor system, VolatileRead obtains the very latest value written to a memory location by any processor. This might require flushing processor caches.
对于 Thread.VolatileWrite:
Writes a value to a field immediately, so that the value is visible to all processors in the computer.
这看起来比单独的存储/加载栅栏(释放/获取)更严格,特别是关于刷新处理器缓存的部分,即比
volatile
更严格的保证.但随后同一份文件说:In C#, using the volatile modifier on a field guarantees that all access to that field uses VolatileRead or VolatileWrite
所以我的问题是 -
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
variable uses(-ed) 在过时的 IA 处理器架构 (Itanium) 上使用较弱的内存模型获取/释放语义。 volatile
修饰符避免编译器优化,也可以使用带有 lock
的指令前缀以保证一致性。 总而言之,编译器可能会使用各种技巧来遵守 C# memory model ,其中指出:
- No reads or writes can move before a volatile read or after a volatile write
- All writes have the effect of volatile write
关于c# - c# 中的 volatile 字段实际上保证了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59726742/