次の方法で共有


Volatile クラス

定義

揮発性メモリの操作を実行するためのメソッドを格納します。

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

注釈

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

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

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

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

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

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

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

Note

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

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

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

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

    Note

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

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

メソッド

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)

指定したオブジェクト参照を指定したフィールドに書き込みます。 これが求められるシステムにおいて、プロセッサがメモリ操作を並べ替えるのを防止するメモリ バリアを挿入します。つまり、コード内でこのメソッドの前に読み取りまたは書き込みが配置されている場合、プロセッサはその操作をこのメソッドの後へ移動できなくなります。

適用対象

こちらもご覧ください