Dan*_*ker 7 .net c# atomic memory-alignment
C#规范(ECMA-334和ISO/IEC 23270)有一段关于读写的原子性:
12.5变量引用的原子性
以下数据类型的读取和写入应为原子:bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型.此外,在先前列表中具有基础类型的枚举类型的读取和写入也应该是原子的.其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,不一定是原子的.
但我很难想象永远是真的.例如,我可以使用StructLayout属性布局结构,并强制字段不对齐:
// sizeof(MyStruct) == 9
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyStruct
{
public byte pad; // Offset: 0
public int value1; // Offset: 1
public int value2; // Offset: 5
}
Run Code Online (Sandbox Code Playgroud)
现在,当我这样做,我会觉得写的int是不是原子的,因为它没有对齐的自然边界:
MyStruct myStruct = new MyStruct();
myStruct.value1 = 20;
Run Code Online (Sandbox Code Playgroud)
那么,它是绝对原子的(就像规范所说的那样),还是不能保证是原子的(例如在x86上)?无论哪种方式,你有任何消息来支持这个吗?
我认为你是对的...在某些情况下,如果你故意偏离你的方式,系统将不会按照语言规范行事.重要的是,ECMA-335在分区I第12.6.6节中明确说明了这一点:
符合要求的CLI应保证 当对位置的所有写访问都是原子时,对正确对齐的内存位置的读写访问不大于本机字大小(native int类型的大小)是原子的(参见§I.12.6.2).大小相同.原子写入除了写入之外不得改变任何位.除非使用显式布局控制(请参阅分区II(控制实例布局))来更改默认行为,否则应正确对齐不大于自然字大小(本机int的大小)的数据元素.对象引用应被视为存储在本机字大小中.
(大胆强调我的;斜体是在规范中.)