Interlocked クラス

定義

複数のスレッドで共有される変数に分割不可能な操作を提供します。

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

次のコード例は、スレッド セーフなリソース ロック メカニズムを示しています。

using namespace System;
using namespace System::Threading;

const int numThreads = 10;
const int numThreadIterations = 5;
ref class MyInterlockedExchangeExampleClass
{
public:
   static void MyThreadProc()
   {
      for ( int i = 0; i < numThreadIterations; i++ )
      {
         UseResource();
         
         //Wait 1 second before next attempt.
         Thread::Sleep( 1000 );

      }
   }


private:
   //A simple method that denies reentrancy.
   static bool UseResource()
   {
      
      //0 indicates that the method is not in use.
      if ( 0 == Interlocked::Exchange( usingResource, 1 ) )
      {
         Console::WriteLine( " {0} acquired the lock", Thread::CurrentThread->Name );
         
         //Code to access a resource that is not thread safe would go here.
         //Simulate some work
         Thread::Sleep( 500 );
         Console::WriteLine( " {0} exiting lock", Thread::CurrentThread->Name );
         
         //Release the lock
         Interlocked::Exchange( usingResource, 0 );
         return true;
      }
      else
      {
         Console::WriteLine( " {0} was denied the lock", Thread::CurrentThread->Name );
         return false;
      }
   }


   //0 for false, 1 for true.
   static int usingResource;
};

int main()
{
   Thread^ myThread;
   Random^ rnd = gcnew Random;
   for ( int i = 0; i < numThreads; i++ )
   {
      myThread = gcnew Thread( gcnew ThreadStart( MyInterlockedExchangeExampleClass::MyThreadProc ) );
      myThread->Name = String::Format( "Thread {0}", i + 1 );
      
      //Wait a random amount of time before starting next thread.
      Thread::Sleep( rnd->Next( 0, 1000 ) );
      myThread->Start();

   }
}
using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 10;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for(int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
            
                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }
        }

        private static void MyThreadProc()
        {
            for(int i = 0; i < numThreadIterations; i++)
            {
                UseResource();
            
                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if(0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
            
                //Code to access a resource that is not thread safe would go here.
            
                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
            
                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}
Imports System.Threading

Namespace InterlockedExchange_Example
    Class MyInterlockedExchangeExampleClass
        '0 for false, 1 for true.
        Private Shared usingResource As Integer = 0

        Private Const numThreadIterations As Integer = 5
        Private Const numThreads As Integer = 10

        <MTAThread> _
        Shared Sub Main()
            Dim myThread As Thread
            Dim rnd As New Random()

            Dim i As Integer
            For i = 0 To numThreads - 1
                myThread = New Thread(AddressOf MyThreadProc)
                myThread.Name = String.Format("Thread{0}", i + 1)

                'Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000))
                myThread.Start()
            Next i
        End Sub

        Private Shared Sub MyThreadProc()
            Dim i As Integer
            For i = 0 To numThreadIterations - 1
                UseResource()

                'Wait 1 second before next attempt.
                Thread.Sleep(1000)
            Next i
        End Sub 

        'A simple method that denies reentrancy.
        Shared Function UseResource() As Boolean
            '0 indicates that the method is not in use.
            If 0 = Interlocked.Exchange(usingResource, 1) Then
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name)

                'Code to access a resource that is not thread safe would go here.
                'Simulate some work
                Thread.Sleep(500)

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name)

                'Release the lock
                Interlocked.Exchange(usingResource, 0)
                Return True
            Else
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name)
                Return False
            End If
        End Function 
    End Class 
End Namespace

注釈

このクラスのメソッドは、スレッドが他のスレッドからアクセスできる変数を更新している間、または 2 つのスレッドが別々のプロセッサで同時に実行されている場合に、スケジューラがコンテキストを切り替えたときに発生する可能性があるエラーから保護するのに役立ちます。 このクラスのメンバーは例外をスローしません。

and Decrement メソッドはIncrement変数をインクリメントまたはデクリメントし、結果の値を 1 回の操作に格納します。 ほとんどのコンピューターでは、変数のインクリメントはアトミック操作ではなく、次の手順を必要とします。

  1. インスタンス変数からレジスタに値を読み込みます。

  2. 値をインクリメントまたはデクリメントします。

  3. 値をインスタンス変数に格納します。

使用 Increment しない場合は、 Decrement最初の 2 つの手順を実行した後にスレッドを割り込むことができます。 その後、別のスレッドで 3 つのステップすべてを実行できます。 最初のスレッドが実行を再開すると、インスタンス変数の値が上書きされ、2 番目のスレッドによって実行された増分またはデクリメントの影響が失われます。

このメソッドは Add 、整数値を整数変数にアトミックに追加し、変数の新しい値を返します。

メソッドは Exchange 、指定された変数の値をアトミックに交換します。 このメソッドは CompareExchange 、比較の結果に基づいて、2 つの値を比較し、いずれかの変数に 3 番目の値を格納する 2 つの操作を組み合わせます。 比較操作と交換操作はアトミック操作として実行されます。

共有変数への書き込みアクセスまたは読み取りアクセスがアトミックであることを確認します。 そうしないと、データが破損しているか、読み込まれた値が正しくない可能性があります。

メソッド

Add(Int32, Int32)

分割不可能な操作として、2 つの 32 ビット整数を加算し、最初の整数を合計で置き換えます。

Add(Int64, Int64)

分割不可能な操作として、2 つの 64 ビット整数を加算し、最初の整数を合計で置き換えます。

Add(UInt32, UInt32)

分割不可能な操作として、2 つの 32 ビット符号なし整数を加算し、最初の整数を合計で置き換えます。

Add(UInt64, UInt64)

分割不可能な操作として、2 つの 64 ビット符号なし整数を加算し、最初の整数を合計で置き換えます。

And(Int32, Int32)

分割不可能な操作として、2 つの 32 ビット符号付き整数のビットごとの "AND" を計算し、最初の整数を結果で置き換えます。

And(Int64, Int64)

分割不可能な操作として、2 つの 64 ビット符号付き整数のビットごとの "AND" を計算し、最初の整数を結果で置き換えます。

And(UInt32, UInt32)

分割不可能な操作として、2 つの 32 ビット符号なし整数のビットごとの "AND" を計算し、最初の整数を結果で置き換えます。

And(UInt64, UInt64)

分割不可能な操作として、2 つの 64 ビット符号なし整数のビットごとの "AND" を計算し、最初の整数を結果で置き換えます。

CompareExchange(Double, Double, Double)

2 つの倍精度浮動小数点数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(Int32, Int32, Int32)

2 つの 32 ビット符号付き整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(Int64, Int64, Int64)

2 つの 64 ビット符号付き整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(IntPtr, IntPtr, IntPtr)

2 つのプラットフォーム固有のハンドルまたはポインターが等しいかどうかを比較します。等しい場合は、最初の 1 つを置き換えます。

CompareExchange(Object, Object, Object)

2 つのオブジェクトの参照が等値であるかどうかを比較します。等しい場合は、最初のオブジェクトを置き換えます。

CompareExchange(Single, Single, Single)

2 つの単精度浮動小数点数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(UInt32, UInt32, UInt32)

2 つの 32 ビット符号なし整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(UInt64, UInt64, UInt64)

2 つの 64 ビット符号なし整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

2 つのプラットフォーム固有のハンドルまたはポインターが等しいかどうかを比較します。等しい場合は、最初の 1 つを置き換えます。

CompareExchange<T>(T, T, T)

指定した参照型 T の 2 つのインスタンスの参照が等しいかどうかを比較します。等しい場合は、最初の 1 つを置き換えます。

Decrement(Int32)

分割不可能な操作として、指定した変数をデクリメントし、結果を格納します。

Decrement(Int64)

分割不可能な操作として、指定した変数をデクリメントしてその結果を格納します。

Decrement(UInt32)

分割不可能な操作として、指定した変数をデクリメントし、結果を格納します。

Decrement(UInt64)

分割不可能な操作として、指定した変数をデクリメントし、結果を格納します。

Exchange(Double, Double)

分割不可能な操作として、指定した値を倍精度浮動小数点数として設定し、元の値を返します。

Exchange(Int32, Int32)

分割不可能な操作として、指定した値を 32 ビット符号付き整数として設定し、元の値を返します。

Exchange(Int64, Int64)

分割不可能な操作として、指定した値を 64 ビット符号付き整数として設定し、元の値を返します。

Exchange(IntPtr, IntPtr)

分割不可能な操作として、プラットフォーム固有のハンドルまたはポインターに指定した値を設定し、元の値を返します。

Exchange(Object, Object)

分割不可能な操作として、指定した値をオブジェクトとして設定し、元のオブジェクトへの参照を返します。

Exchange(Single, Single)

分割不可能な操作として、指定した値を単精度浮動小数点数として設定し、元の値を返します。

Exchange(UInt32, UInt32)

分割不可能な操作として、指定した値を 32 ビット符号なし整数として設定し、元の値を返します。

Exchange(UInt64, UInt64)

分割不可能な操作として、指定した値を 64 ビット符号なし整数として設定し、元の値を返します。

Exchange(UIntPtr, UIntPtr)

分割不可能な操作として、プラットフォーム固有のハンドルまたはポインターに指定した値を設定し、元の値を返します。

Exchange<T>(T, T)

分割不可能な操作として、指定した型 T の変数に指定した値を設定し、元の値を返します。

Increment(Int32)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。

Increment(Int64)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。

Increment(UInt32)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。

Increment(UInt64)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。

MemoryBarrier()

メモリ アクセスを同期します。現在のスレッドを実行中のプロセッサは、MemoryBarrier() を呼び出す前のメモリ アクセスを MemoryBarrier() の呼び出し後のメモリ アクセス以降に実行するように命令を並べ替えることはできなくなります。

MemoryBarrierProcessWide()

すべての CPU からの読み取りと書き込みがバリアを超えて移動できるように、プロセス全体のメモリ バリアを提供します。

Or(Int32, Int32)

分割不可能な操作として、2 つの 32 ビット符号付き整数のビットごとの "OR" を計算し、最初の整数を結果で置き換えます。

Or(Int64, Int64)

分割不可能な操作として、2 つの 64 ビット符号付き整数のビットごとの "OR" を計算し、最初の整数を結果で置き換えます。

Or(UInt32, UInt32)

分割不可能な操作として、2 つの 32 ビット符号なし整数のビットごとの "OR" を計算し、最初の整数を結果で置き換えます。

Or(UInt64, UInt64)

分割不可能な操作として、2 つの 64 ビット符号なし整数のビットごとの "OR" を計算し、最初の整数を結果で置き換えます。

Read(Int64)

分割不可能な操作として 64 ビット値を読み込んで返します。

Read(UInt64)

分割不可能な操作として 64 ビットの符号なしの値を読み込んで返します。

SpeculationBarrier()

このポイントを超えた予測実行を保留中の読み取りと書き込みが完了するまでブロックする、メモリ フェンスを定義します。

適用対象

スレッド セーフ

この型はスレッド セーフです。

こちらもご覧ください