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.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つのスレッドが実行されているときに、スケジューラがコンテキストを切り替えるときに発生する可能性のあるエラーから保護するのに役立ちます。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メソッドは、変数をインクリメントまたはデクリメントし、結果の値を1回の操作で格納します。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つの値を比較し、変数の1つに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.

こちらもご覧ください