C# 为什么没有Volatile.Read(ref T location),其中T:struct?

C# 为什么没有Volatile.Read(ref T location),其中T:struct?,c#,multithreading,thread-safety,volatile,C#,Multithreading,Thread Safety,Volatile,对于所有的原语和引用类型都有一个方法,为什么没有针对结构的方法?同样的情况也适用于。同样,旧方法也没有用于结构的方法 这背后的原因是什么?我可以在一个类中声明volatile结构,为什么我不能用这些方法进行volatile读取?如果volatile操作也是原子的,那么只有在volatile操作中才有保证,除了最简单的结构(例如,一个基元或引用类型的字段,或者任何适合64位/8字节的结构)之外,这不是所有的情况 例如,您对768位/96字节结构上的这种易失性方法有什么期望?任何大于支持的最大原子操

对于所有的原语和引用类型都有一个方法,为什么没有针对结构的方法?同样的情况也适用于。同样,旧方法也没有用于结构的方法


这背后的原因是什么?我可以在一个类中声明volatile结构,为什么我不能用这些方法进行volatile读取?

如果volatile操作也是原子的,那么只有在volatile操作中才有保证,除了最简单的结构(例如,一个基元或引用类型的字段,或者任何适合64位/8字节的结构)之外,这不是所有的情况

例如,您对768位/96字节结构上的这种易失性方法有什么期望?任何大于支持的最大原子操作的操作实际上都会导致多个易失性写操作,每个写操作都会在没有任何保证的情况下立即可见


在.NET的Microsoft实现中,long和double Volatile方法是原子的。即使在32位体系结构上,也要以在此类体系结构中使用互锁操作为代价。

如果易失性操作也是原子的,则只能保证它们是原子的,这不是所有操作的情况,而是最简单的结构,例如一个基元或引用类型的字段,或任何适合64位/8字节的结构

例如,您对768位/96字节结构上的这种易失性方法有什么期望?任何大于支持的最大原子操作的操作实际上都会导致多个易失性写操作,每个写操作都会在没有任何保证的情况下立即可见


在.NET的Microsoft实现中,long和double Volatile方法是原子的。即使是在32位体系结构上,也要以在这种体系结构中使用互锁操作为代价。

我想这是因为struct在内存中可以有任意大小,所以通常不能以原子方式读取它。C语言产生了一种错觉,即只需一次操作就可以读取或写入一个struct。但这只是一种错觉,处理器只能访问字段。如果你不能正确理解Volatile类型,那么它是非常危险的,如果你不能正确使用它,那么你将会得到线程竞赛bug,这是完全不可能调试的。您可能需要一个完整的MemoryBarrier,但很有可能您不应该忽略这里的lock关键字。当然,我们不知道,你没有表现出你的意图。不正确地使用也是一个很大的错误。我想这是因为struct在内存中可以有任意大小,所以通常不能原子地读取它。C语言造成了一种错觉,即您可以通过单个操作读取或写入struct。但这只是一种错觉,处理器只能访问字段。如果你不能正确理解Volatile类型,那么它是非常危险的,如果你不能正确使用它,那么你将会得到线程竞赛bug,这是完全不可能调试的。您可能需要一个完整的MemoryBarrier,但很有可能您不应该忽略这里的lock关键字。当然,我们不知道,你没有表现出你的意图。不正确地使用也是一个很大的错误。我想知道,Volatile。在32位体系结构上,使用double或long读取也是原子的吗?在MS实现中,long和double Volatile方法是原子的,即使在32位ARCH上也是原子的,代价是在此类ARCH中使用联锁操作。我想知道,Volatile.Read with double或long在32位体系结构上也是原子的吗?在MS实现中,long和double Volatile方法是原子的,即使在32位ARCH上也是原子的,但代价是在此类ARCH中使用联锁操作。