2013-03-06 47 views
6

C#的规范(ECMA-334ISO/IEC 23270)具有约的原子段的读取和写入:在.NET中读取和写入未对齐的字段绝对原子?

12.5原子性变量引用

读取的和下面的数据类型的写入应为原子: bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型。另外,在前面列表中读取和写入具有基础类型的枚举类型也应该是原子的。其他类型(包括long,ulong,double和decimal)以及用户定义类型的读取和写入不必是原子的。

但我很难想象,永远是真的。例如,我可以布局使用StructLayout attribute一个结构,并迫使字段没有对齐:

// 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 
} 

现在,当我这样做,我会觉得在写int原子,因为它是未对齐于自然边界:

MyStruct myStruct = new MyStruct(); 
myStruct.value1 = 20; 

那么,它肯定原子(如规范说)呢,还是不能保证是原子(例如,在x86上)?无论哪种方式,您是否有任何资源可以支持?

+2

乔恩,当然,正确的;如果故意破坏对齐,那么你也故意破坏原子性。如果你这样做会伤害,那么**不要那样做**。 – 2013-03-06 15:50:44

回答

6

我认为你是对的......在有些情况下,如果你故意违规,系统将不会按照语言规范行事。重要的是,ECMA-335使得这个明确的分区我部分12.6.6:

一个符合CLI须保证读取和写入访问正确对齐内存 位置不超过本地字大小(类型的大小大本地int)是原子 (见§I.12.6.2),当一个位置的所有写入访问都是相同的大小。原子写入应该不会改变除写入的那些位以外的其他位。 除非使用明确的布局控制(请参阅 分区II(控制实例布局))来更改默认行为,否则应正确对齐大于自然字大小(本地int大小)的数据元素 。对象 引用应被视为它们以本地字大小存储。

(粗体重点煤矿;斜体字是在规范中)