web-dev-qa-db-ja.com

C#でアトミックな操作は何ですか?

C#の操作がアトミックであるかどうかを知る体系的な方法はありますか?または、一般的なガイドラインや経験則はありますか?

49
Eric

より完全/詳細なもの:

32ビット値型の読み取りと書き込みはアトミックです。これには、次の組み込み値(構造体)型が含まれます:bool, char, byte, sbyte, short, ushort, int, uint, float。次のタイプは(とりわけ)アトミックであるとは限りません。decimal, double, long, ulong

例えば.

int x;
x = 10; // atomic
decimal d;

d = 10m; // not atomic

参照の割り当てもアトミック操作です。

private String _text;
public void Method(String text)
{
  _text = text; // atomic
}
32
Peter Ritchie

はい。 CLI仕様をお読みください: http://www.ecma-international.org/publications/standards/Ecma-335.htm 。例えば:

I.12.6.6原子の読み取りと書き込み

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

[注:クラスライブラリの一部としてその目的のために提供されるメソッドを除き、メモリのアトミック更新(読み取り-変更-書き込み)についての保証はありません(パーティションIVを参照)。小さなデータ項目への直接書き込みをサポートしていないハードウェアでアトミックな読み取り/変更/書き込みを行うには、「小さなデータ項目」(ネイティブのWordサイズ以下の項目)のアトミックな書き込みが必要です。終了ノート]

[注:一部の実装では、データが8バイト境界に配置されているときにアトミック操作を実行する場合でも、ネイティブintのサイズが32ビットの場合、8バイトデータへのアトミックアクセスは保証されません。終了ノート]

64ビットの長い質問については、Eric Lippertがここで答えています。 http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are- different-part-two.aspx

CLI仕様は、実際により強力な保証を行います。 CLIは、プロセッサーの自然なポインターサイズのサイズ(またはそれ以下)である値型の変数の読み取りおよび書き込みがアトミックであることを保証します。 64ビットバージョンのCLRの64ビットオペレーティングシステムでC#コードを実行している場合、64ビットの倍精度および長整数の読み取りと書き込みもアトミックであることが保証されます。 C#言語はそれを保証しませんが、ランタイム仕様は保証します。 (CLIの実装によって実装されていない環境でC#コードを実行している場合、もちろんその保証に頼ることはできません。提供する保証について知りたい場合は、ランタイムを販売したベンダーに問い合わせてください)

アトミックアクセスに関するもう1つの微妙な点は、読み取りまたは書き込みされる変数がメモリ内の適切な場所に配置されたストレージに関連付けられている場合にのみ、基になるプロセッサがアトミック性を保証することです。最終的に、変数はメモリへのポインタとしてどこかに実装されます。 32ビットオペレーティングシステムでは、読み取りまたは書き込みがアトミックであることを保証するために、そのポインターは4で均等に分割可能でなければならず、64ビットオペレーティングシステムでは、8で均等に分割可能でなければなりません。

29
Chris Shain

CLI仕様から here を取得できます:

「準拠するCLIは、ネイティブWordサイズ(ネイティブint型のサイズ)以下の適切に配置されたメモリ位置への読み取りおよび書き込みアクセスがアトミックであることを保証します...」

C#仕様のセクション12.5 here

「次のデータ型の読み取りと書き込みはアトミックです:bool、char、byte、sbyte、short、ushort、uint、int、float、および参照タイプ。」また、「…アトミックなread-modify-インクリメントまたはデクリメントの場合などに書き込みます。」

this でインクリメント操作をアトミックにします。

6
Secko