Interlocked Interlocked Interlocked Interlocked Class

定義

複数のスレッドで共有される変数に分割不可能な操作を提供します。Provides atomic operations for variables that are shared by multiple threads.

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

次のコード例では、スレッド セーフであるリソースのロック機構を示します。The following code example shows a thread-safe resource locking mechanism.

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
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 'Main

        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 つのスレッドは別々 のプロセッサで同時に実行するときに発生する可能性があるエラーに対して保護します。The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors. このクラスのメンバーは、例外をスローしません。The members of this class do not throw exceptions.

IncrementDecrementメソッドの増減変数と、単一操作で、結果の値を格納します。The Increment and Decrement methods increment or decrement a variable and store the resulting value in a single operation. ほとんどのコンピューターで変数のインクリメント、次の手順を必要とする、分割不可能な操作ではありません。On most computers, incrementing a variable is not an atomic operation, requiring the following steps:

  1. レジスタにインスタンス変数から値を読み込みます。Load a value from an instance variable into a register.

  2. インクリメントまたはデクリメント値。Increment or decrement the value.

  3. インスタンス変数に値を格納します。Store the value in the instance variable.

使用しない場合IncrementDecrementスレッドは、最初の 2 つの手順を実行後に割り込まれることができます。If you do not use Increment and Decrement, a thread can be preempted after executing the first two steps. 別のスレッドは、すべての 3 つの手順を実行できます。Another thread can then execute all three steps. 最初のスレッドが実行を再開し、インスタンス変数の値が上書きされますインクリメントまたはデクリメントが 2 番目のスレッドによって実行されるの効果が失われます。When the first thread resumes execution, it overwrites the value in the instance variable, and the effect of the increment or decrement performed by the second thread is lost.

Addメソッドはアトミックに整数値を整数変数を追加し、変数の新しい値を返します。The Add method atomically adds an integer value to an integer variable and returns the new value of the variable.

Exchangeメソッドが、指定された変数の値をアトミックに交換します。The Exchange method atomically exchanges the values of the specified variables. CompareExchangeメソッドで 2 つの操作を組み合わせています。 比較の結果に基づいて、変数のいずれかの値の 2 つの値を比較すると、3 つ目を格納します。The CompareExchange method combines two operations: comparing two values and storing a third value in one of the variables, based on the outcome of the comparison. 比較および交換操作はアトミック操作として実行されます。The compare and exchange operations are performed as an atomic operation.

任意の書き込みまたは共有変数への読み取りアクセスがアトミックであることを確認します。Ensure that any write or read access to a shared variable is atomic. それ以外の場合、データが壊れている可能性があります。 または読み込まれた値が正しくない可能性があります。Otherwise, the data might be corrupted or the loaded value might be incorrect.

メソッド

Add(Int32, Int32) Add(Int32, Int32) Add(Int32, Int32) Add(Int32, Int32)

分割不可能な操作として、2 つの 32 ビット整数を加算し、最初の整数を合計で置き換えます。Adds two 32-bit integers and replaces the first integer with the sum, as an atomic operation.

Add(Int64, Int64) Add(Int64, Int64) Add(Int64, Int64) Add(Int64, Int64)

分割不可能な操作として、2 つの 64 ビット整数を加算し、最初の整数を合計で置き換えます。Adds two 64-bit integers and replaces the first integer with the sum, as an atomic operation.

CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double) CompareExchange(Double, Double, Double)

2 つの倍精度浮動小数点数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。Compares two double-precision floating point numbers for equality and, if they are equal, replaces the first value.

CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32) CompareExchange(Int32, Int32, Int32)

2 つの 32 ビット符号付き整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.

CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64) CompareExchange(Int64, Int64, Int64)

2 つの 64 ビット符号付き整数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。Compares two 64-bit signed integers for equality and, if they are equal, replaces the first value.

CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr) CompareExchange(IntPtr, IntPtr, IntPtr)

2 つのプラットフォーム固有のハンドルまたはポインターが等しいかどうかを比較します。等しい場合は、最初の 1 つを置き換えます。Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one.

CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object) CompareExchange(Object, Object, Object)

2 つのオブジェクトの参照が等値であるかどうかを比較します。等しい場合は、最初のオブジェクトを置き換えます。Compares two objects for reference equality and, if they are equal, replaces the first object.

CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single) CompareExchange(Single, Single, Single)

2 つの単精度浮動小数点数が等しいかどうかを比較します。等しい場合は、最初の値を置き換えます。Compares two single-precision floating point numbers for equality and, if they are equal, replaces the first value.

CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T) CompareExchange<T>(T, T, T)

指定した参照型 T の 2 つのインスタンスの参照が等しいかどうかを比較します。等しい場合は、最初の 1 つを置き換えます。Compares two instances of the specified reference type T for reference equality and, if they are equal, replaces the first one.

Decrement(Int32) Decrement(Int32) Decrement(Int32) Decrement(Int32)

分割不可能な操作として、指定した変数をデクリメントし、結果を格納します。Decrements a specified variable and stores the result, as an atomic operation.

Decrement(Int64) Decrement(Int64) Decrement(Int64) Decrement(Int64)

分割不可能な操作として、指定した変数をデクリメントしてその結果を格納します。Decrements the specified variable and stores the result, as an atomic operation.

Exchange(Single, Single) Exchange(Single, Single) Exchange(Single, Single) Exchange(Single, Single)

分割不可能な操作として、指定した値を単精度浮動小数点数として設定し、元の値を返します。Sets a single-precision floating point number to a specified value and returns the original value, as an atomic operation.

Exchange(Object, Object) Exchange(Object, Object) Exchange(Object, Object) Exchange(Object, Object)

分割不可能な操作として、指定した値をオブジェクトとして設定し、元のオブジェクトへの参照を返します。Sets an object to a specified value and returns a reference to the original object, as an atomic operation.

Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr) Exchange(IntPtr, IntPtr)

分割不可能な操作として、プラットフォーム固有のハンドルまたはポインターに指定した値を設定し、元の値を返します。Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation.

Exchange(Double, Double) Exchange(Double, Double) Exchange(Double, Double) Exchange(Double, Double)

分割不可能な操作として、指定した値を倍精度浮動小数点数として設定し、元の値を返します。Sets a double-precision floating point number to a specified value and returns the original value, as an atomic operation.

Exchange(Int32, Int32) Exchange(Int32, Int32) Exchange(Int32, Int32) Exchange(Int32, Int32)

分割不可能な操作として、指定した値を 32 ビット符号付き整数として設定し、元の値を返します。Sets a 32-bit signed integer to a specified value and returns the original value, as an atomic operation.

Exchange(Int64, Int64) Exchange(Int64, Int64) Exchange(Int64, Int64) Exchange(Int64, Int64)

分割不可能な操作として、指定した値を 64 ビット符号付き整数として設定し、元の値を返します。Sets a 64-bit signed integer to a specified value and returns the original value, as an atomic operation.

Exchange<T>(T, T) Exchange<T>(T, T) Exchange<T>(T, T) Exchange<T>(T, T)

分割不可能な操作として、指定した型 T の変数に指定した値を設定し、元の値を返します。Sets a variable of the specified type T to a specified value and returns the original value, as an atomic operation.

Increment(Int32) Increment(Int32) Increment(Int32) Increment(Int32)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。Increments a specified variable and stores the result, as an atomic operation.

Increment(Int64) Increment(Int64) Increment(Int64) Increment(Int64)

分割不可能な操作として、指定した変数をインクリメントし、結果を格納します。Increments a specified variable and stores the result, as an atomic operation.

MemoryBarrier() MemoryBarrier() MemoryBarrier() MemoryBarrier()

メモリ アクセスを次のように同期します。現在のスレッドを実行するプロセッサは、MemoryBarrier() を呼び出す前のメモリ アクセスを MemoryBarrier() の呼び出し後のメモリ アクセスより後に実行するように命令を並べ替えることはできません。Synchronizes memory access as follows: The processor that executes the current thread cannot reorder instructions in such a way that memory accesses before the call to MemoryBarrier() execute after memory accesses that follow the call to MemoryBarrier().

MemoryBarrierProcessWide() MemoryBarrierProcessWide() MemoryBarrierProcessWide() MemoryBarrierProcessWide()

すべての CPU からの読み取りと書き込みがバリアを超えて移動できるように、プロセス全体のメモリ バリアを提供します。Provides a process-wide memory barrier that ensures that reads and writes from any CPU cannot move across the barrier.

Read(Int64) Read(Int64) Read(Int64) Read(Int64)

分割不可能な操作として 64 ビット値を読み込んで返します。Returns a 64-bit value, loaded as an atomic operation.

SpeculationBarrier() SpeculationBarrier() SpeculationBarrier() SpeculationBarrier()

このポイントを超えた予測実行を保留中の読み取りと書き込みが完了するまでブロックする、メモリ フェンスを定義します。Defines a memory fence that blocks speculative execution past this point until pending reads and writes are complete.

適用対象

スレッド セーフ

この型はスレッド セーフです。This type is thread safe.

こちらもご覧ください