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

설명

이 클래스의 메서드는 스레드가 다른 스레드에서 액세스할 수 있는 변수를 업데이트하는 동안 또는 두 스레드가 별도의 프로세서에서 동시에 실행되는 경우 스케줄러가 컨텍스트를 전환할 때 발생할 수 있는 오류로부터 보호하는 데 도움이 됩니다. 이 클래스의 멤버는 예외를 throw하지 않습니다.

Decrement 메서드는 Increment 변수를 증가 또는 감소시키고 결과 값을 단일 작업에 저장합니다. 대부분의 컴퓨터에서 변수를 증가시키는 것은 원자성 작업이 아니며 다음 단계를 수행해야 합니다.

  1. 인스턴스 변수의 값을 레지스터에 로드합니다.

  2. 값을 증가 또는 감소합니다.

  3. 인스턴스 변수에 값을 저장합니다.

사용하지 Increment Decrement않는 경우 처음 두 단계를 실행한 후 스레드를 선점할 수 있습니다. 그러면 다른 스레드가 세 단계를 모두 실행할 수 있습니다. 첫 번째 스레드가 실행을 다시 시작하면 인스턴스 변수의 값을 덮어쓰고 두 번째 스레드에서 수행하는 증가 또는 감소의 효과가 손실됩니다.

이 메서드는 Add 정수 변수에 정수 값을 원자성으로 추가하고 변수의 새 값을 반환합니다.

메서드는 Exchange 지정된 변수의 값을 원자성으로 교환합니다. 이 메서드는 CompareExchange 두 값을 비교하고 비교 결과에 따라 변수 중 하나에 세 번째 값을 저장하는 두 가지 연산을 결합합니다. 비교 및 교환 작업은 원자성 작업으로 수행됩니다.

공유 변수에 대한 쓰기 또는 읽기 액세스가 원자성인지 확인합니다. 그렇지 않으면 데이터가 손상되거나 로드된 값이 올바르지 않을 수 있습니다.

메서드

Add(Int32, Int32)

원자 단위 연산으로 두 32비트 정수를 더하고 첫 번째 정수를 합계로 바꿉니다.

Add(Int64, Int64)

원자성 연산으로 두 64비트 정수를 더하고 첫 번째 정수를 합계로 바꿉니다.

Add(UInt32, UInt32)

원자성 연산으로 두 부호 없는 32비트 정수를 더하고 첫 번째 정수를 합계로 바꿉니다.

Add(UInt64, UInt64)

원자성 연산으로 두 부호 없는 64비트 정수를 더하고 첫 번째 정수를 합계로 바꿉니다.

And(Int32, Int32)

원자성 연산으로 두 부호 있는 32비트 정수를 비트 “AND” 연산하고 첫 번째 정수를 결과로 바꿉니다.

And(Int64, Int64)

원자성 연산으로 두 부호 있는 64비트 정수를 비트 “AND” 연산하고 첫 번째 정수를 결과로 바꿉니다.

And(UInt32, UInt32)

원자성 연산으로 두 부호 없는 32비트 정수를 비트 “AND” 연산하고 첫 번째 정수를 결과로 바꿉니다.

And(UInt64, UInt64)

원자성 연산으로 두 부호 없는 64비트 정수를 비트 “AND” 연산하고 첫 번째 정수를 결과로 바꿉니다.

CompareExchange(Double, Double, Double)

두 배 정밀도 부동 소수점 숫자가 같은지 비교하여 같으면 두 값 중 하나를 바꿉니다.

CompareExchange(Int32, Int32, Int32)

두 개의 부호 있는 32비트 정수가 같은지 비교하여 같으면 첫 번째 값을 바꿉니다.

CompareExchange(Int64, Int64, Int64)

두 개의 부호 있는 64비트 정수가 같은지 비교하여 같으면 첫 번째 값을 바꿉니다.

CompareExchange(IntPtr, IntPtr, IntPtr)

두 플랫폼별 핸들이나 포인터가 같은지 비교하고, 같으면 첫 번째 값을 바꿉니다.

CompareExchange(Object, Object, Object)

두 개체의 참조가 같은지 비교하고, 같으면 첫 번째 개체를 바꿉니다.

CompareExchange(Single, Single, Single)

두 단정밀도 부동 소수점 숫자가 같은지 비교하여 같으면 첫 번째 값을 바꿉니다.

CompareExchange(UInt32, UInt32, UInt32)

두 개의 부호 없는 32비트 정수가 같은지 비교하여 같으면 첫 번째 값을 바꿉니다.

CompareExchange(UInt64, UInt64, UInt64)

두 개의 부호 없는 64비트 정수가 같은지 비교하여 같으면 첫 번째 값을 바꿉니다.

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

두 플랫폼별 핸들이나 포인터가 같은지 비교하고, 같으면 첫 번째 값을 바꿉니다.

CompareExchange<T>(T, T, T)

지정된 참조 형식 T의 두 인스턴스에 대한 참조가 같은지 비교하고, 같으면 첫 번째 값을 바꿉니다.

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)

원자성 연산으로 두 부호 있는 32비트 정수를 비트 “OR” 연산하고 첫 번째 정수를 결과로 바꿉니다.

Or(Int64, Int64)

원자성 연산으로 두 부호 있는 64비트 정수를 비트 “OR” 연산하고 첫 번째 정수를 결과로 바꿉니다.

Or(UInt32, UInt32)

원자성 연산으로 두 부호 없는 32비트 정수를 비트 “OR” 연산하고 첫 번째 정수를 결과로 바꿉니다.

Or(UInt64, UInt64)

원자성 연산으로 두 부호 없는 64비트 정수를 비트 “OR” 연산하고 첫 번째 정수를 결과로 바꿉니다.

Read(Int64)

원자 단위 연산으로 로드된 64비트 값을 반환합니다.

Read(UInt64)

원자성 연산으로 로드된 부호 없는 64비트 값을 반환합니다.

SpeculationBarrier()

보류 중인 읽기 및 쓰기가 완료될 때까지 이 지점을 넘는 투기적 실행을 제한하는 메모리 펜스를 정의합니다.

적용 대상

스레드 보안

이 형식은 스레드로부터 안전합니다.

추가 정보