7

C#仕様(ECMA-334およびISO / 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はパーティション I セクション 12.6.6 でこれを明示しています。

適合する CLI は 、ある場所へのすべての書き込みアクセスがある場合、ネイティブ ワード サイズ (ネイティブ int 型のサイズ) を超えない適切に配置されたメモリ位置への読み取りおよび書き込みアクセスがアトミックであることを保証するものとします (§I.12.6.2 を参照)。同じサイズ。アトミック書き込みは、書き込まれたビット以外のビットを変更してはなりません。明示的なレイアウト制御 (パーティション II (インスタンス レイアウトの制御) を参照) を使用してデフォルトの動作を変更しない限り、自然なワード サイズ (ネイティブ int のサイズ) を超えないデータ要素は適切に配置されます。オブジェクト参照は、ネイティブ ワード サイズで格納されているかのように扱われます。

(太字は私の強調です。イタリック体は仕様に含まれています。)

于 2013-03-06T14:19:44.150 に答える