Volatile クラス

定義

揮発性メモリ操作を実行するためのメソッドが含まれています。

public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
継承
Volatile

注釈

マルチプロセッサ システムでは、コンパイラまたはプロセッサのパフォーマンスの最適化により、複数のプロセッサが同じメモリ上で動作しているときに通常のメモリ操作が並べ替えられるように見える場合があります。 揮発性メモリ操作では、操作に関して特定の種類の並べ替えを防止します。 揮発性の書き込み操作では、揮発性書き込みの後に発生するようにスレッドの以前のメモリ操作が並べ替えられるのを防ぎます。 揮発性読み取り操作では、揮発性読み取り前にスレッドの後のメモリ操作が並べ替えられるのを防ぎます。 これらの操作には、パフォーマンスに影響を与える可能性がある一部のプロセッサのメモリ バリアが含まれる場合があります。

たとえば、最初は 0 である 2 つのスレッドと 2 つのInt32 フィールドxyを含む次のシナリオを考えてみましょう。

スレッド 1 スレッド 2
x = 1; int y2 = Volatile.Read(ref y);
Volatile.Write(ref y, 1); int x2 = x;

揮発性の読み取りと書き込みでは、コンパイラやプロセッサなど、各スレッド内の 2 つの操作の並べ替えを防止します。 スレッドが異なるプロセッサで実行される可能性があるマルチプロセッサ システムでも、これらの操作が他のスレッドに対して 1 つのスレッドで実際に発生する順序に関係なく、揮発性操作ではスレッド 2 に y2 == 1x2 == 0が表示されないことが保証されます。 スレッド 1 では、xへの書き込みがyへの揮発性の書き込みの前に発生するように見える必要があり、スレッド 2 では、yの揮発性読み取り後にxの読み取りが行われるように見える必要があります。 したがって、スレッド 2 に y2 == 1が表示される場合は、 x2 == 1も表示する必要があります。

ただし、上記と同じシナリオで、操作が発生する特定のシーケンスを考慮してください。

順番 スレッド 1 スレッド 2
1 x = 1; ...
2 Volatile.Write(ref y, 1); ...
3 ... int y2 = Volatile.Read(ref y);
4 ... int x2 = x;

スレッド 1 の y への揮発性書き込みが、スレッド 2 の y の揮発性読み取り前に発生した場合でも、スレッド 2 に y2 == 0が表示される場合があります。 yへの揮発性の書き込みでは、別のプロセッサ上の次の揮発性y読み取りで更新された値が表示される保証はありません。

Note

  • 揮発性の読み取りと書き込みにより、値がメモリに読み取りまたは書き込まれ、キャッシュされないようにします (プロセッサ レジスタなど)。 したがって、これらの操作を使用して、別のスレッドまたはハードウェアによって更新できるフィールドへのアクセスを同期できます。
  • Volatile クラスは、Int64Doubleなど、一部の 64 ビット型に対する読み取りおよび書き込み操作も提供します。 このような 64 ビット メモリでの揮発性の読み取りと書き込みは、通常の読み取りと書き込みとは異なり、32 ビット プロセッサでもアトミックです。

揮発性メモリ操作は、通常のロックが許容できる代替手段ではない特殊な同期の場合に使用されます。 通常の状況では、C# lock ステートメント、Visual Basic SyncLock ステートメント、および Monitor クラスは、データへのアクセスを同期する最も簡単でエラーが発生しやすい方法を提供し、Lazy<T> クラスは、二重チェックロックを直接使用せずに遅延初期化コードを記述する簡単な方法を提供します。

Volatile.ReadメソッドとVolatile.Writeメソッドを使用すると、言語でサポートされていない機能が有効になります。 例えば次が挙げられます。

  • Visual Basicなどの一部の言語では、揮発性メモリ操作の概念を認識しません。 Volatile クラスは、そのような言語でその機能を提供します。

    Note

    これらのメソッドのいずれかを呼び出すと、1 つのメモリ アクセスにのみ影響します。 フィールドの有効な同期を提供するには、フィールドへのすべてのアクセスで Volatile.ReadVolatile.Writeを使用する必要があります。

  • C# では、フィールドに対して volatile 修飾子を使用すると、そのフィールドへのすべてのアクセスが揮発性メモリ操作であることが保証されますが、 volatile 修飾子を配列要素に適用することはできません。 配列要素では、 Volatile.Read メソッドと Volatile.Write メソッドを使用できます。

メソッド

名前 説明
Read(Boolean)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Byte)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Double)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Int16)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Int32)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Int64)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(IntPtr)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(SByte)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(Single)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(UInt16)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(UInt32)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(UInt64)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read(UIntPtr)

指定したフィールドの値を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Read<T>(T)

指定したフィールドからオブジェクト参照を読み取ります。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの後に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの前に移動できません。

Write(Boolean, Boolean)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Byte, Byte)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Double, Double)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Int16, Int16)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Int32, Int32)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Int64, Int64)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(IntPtr, IntPtr)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(SByte, SByte)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(Single, Single)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(UInt16, UInt16)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(UInt32, UInt32)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(UInt64, UInt64)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write(UIntPtr, UIntPtr)

指定した値を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

Write<T>(T, T)

指定したオブジェクト参照を指定したフィールドに書き込みます。 必要なシステムでは、プロセッサがメモリ操作を並べ替えないようにするメモリ バリアを挿入します。コード内でこのメソッドの前に読み取りまたは書き込みが表示される場合、プロセッサはこのメソッドの後に移動できません。

適用対象

こちらもご覧ください