7

C# 规范(ECMA-334ISO/IEC 23270)有一段关于读写的原子性:

12.5 变量引用的原子性

以下数据类型的读取和写入应是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。此外,具有上一个列表中的基础类型的枚举类型的读取和写入也应该是原子的。其他类型的读取和写入,包括 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
}

现在当我这样做时,我会认为对 的写入int不是原子的,因为它没有与自然边界对齐

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

那么,它绝对是原子的(就像规范所说的那样),还是不能保证是原子的(例如在 x86 上)?无论哪种方式,您是否有任何来源支持这一点?

4

1 回答 1

7

我认为您是对的……在某些情况下,如果您故意不做任何事情,系统将不会按照语言规范运行。重要的是,ECMA-335在第一部分第 12.6.6 节中明确说明了这一点:

符合 CLI 的 CLI 应保证对正确对齐的内存位置的读写访问 不大于本机字大小(本机 int 类型的大小)是原子的(参见 §I.12.6.2)相同的大小。原子写入不应改变除已写入的位之外的任何位。除非使用显式布局控制(参见分区 II(控制实例布局))来更改默认行为,否则不大于自然字长(本机 int 的大小)的数据元素应正确对齐。对象引用应被视为以本机字长存储。

(我的粗体强调;斜体在规范中。)

于 2013-03-06T14:19:44.150 回答