다음을 통해 공유


동기화 기본 형식 개요

.NET은 공유 리소스에 대한 액세스를 동기화하거나 스레드 상호 작용을 조정하는 데 사용할 수 있는 다양한 형식을 제공합니다.

중요합니다

동일한 동기화 기본 인스턴스를 사용하여 공유 리소스의 액세스를 보호합니다. 다른 동기화 기본 인스턴스를 사용하여 동일한 리소스를 보호하는 경우 동기화 기본 형식에서 제공하는 보호를 우회합니다.

WaitHandle 클래스 및 경량 동기화 유형

여러 .NET 동기화 기본 형식은 System.Threading.WaitHandle 클래스에서 파생되며, 이 클래스는 원시 운영 체제 동기화 핸들을 캡슐화하고 스레드 간의 상호 작용을 위한 신호 메커니즘을 사용합니다. 이러한 클래스는 다음과 같습니다.

  • System.Threading.Mutex공유 리소스에 대한 단독 액세스 권한을 부여하는 입니다. 뮤텍스를 소유하는 스레드가 없는 경우 뮤텍스의 상태가 신호로 전송됩니다.
  • System.Threading.Semaphore- 공유 리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한합니다. 세마포의 상태는 개수가 0보다 클 때 신호로 설정되고 개수가 0이면 서명되지 않습니다.
  • System.Threading.EventWaitHandle는 스레드 동기화 이벤트를 나타내며 신호 상태 또는 비신호 상태일 수 있습니다.
  • System.Threading.AutoResetEvent에서 파생되며 신호를 받으면 단일 대기 스레드를 해제한 후 비신호 상태로 자동으로 다시 설정됩니다.
  • System.Threading.ManualResetEvent에서 파생 EventWaitHandle 되고 신호를 받으면 메서드가 호출될 때까지 Reset 신호된 상태로 유지됩니다.

.NET Framework WaitHandle 에서 System.MarshalByRefObject파생되므로 이러한 형식을 사용하여 애플리케이션 도메인 경계를 넘어 스레드의 활동을 동기화할 수 있습니다.

.NET Framework, .NET Core 및 .NET 5 이상에서 이러한 형식 중 일부는 운영 체제 전체에 표시되고 프로세스 간 동기화에 사용할 수 있는 명명된 시스템 동기화 핸들을 나타낼 수 있습니다.

자세한 내용은 API 참조를 WaitHandle 참조하세요.

경량 동기화 유형은 기본 운영 체제 핸들을 사용하지 않으며 일반적으로 더 나은 성능을 제공합니다. 그러나 프로세스 간 동기화에는 사용할 수 없습니다. 이러한 형식을 하나의 애플리케이션 내에서 스레드 동기화에 사용합니다.

이러한 형식 중 일부는 에서 파생된 WaitHandle형식의 대안입니다. 예를 들어, SemaphoreSlimSemaphore에 비해 가벼운 대안입니다.

공유 리소스에 대한 액세스 동기화

.NET은 여러 스레드에서 공유 리소스에 대한 액세스를 제어하는 다양한 동기화 기본 형식을 제공합니다.

모니터 클래스

클래스는 System.Threading.Monitor 리소스를 식별하는 개체에 대한 잠금을 획득하거나 해제하여 공유 리소스에 대한 상호 배타적인 액세스 권한을 부여합니다. 잠금이 유지되는 동안 잠금을 보유하는 스레드는 잠금을 다시 획득하고 해제할 수 있습니다. 다른 스레드는 잠금을 획득하지 못하도록 차단되고 메서드는 Monitor.Enter 잠금이 해제될 때까지 기다립니다. 이 메서드는 Enter 해제된 잠금을 획득합니다. 이 메서드를 사용하여 스레드가 Monitor.TryEnter 잠금을 획득하려고 시도하는 시간을 지정할 수도 있습니다. 클래스에 Monitor 스레드 선호도가 있으므로 잠금을 획득한 스레드는 메서드를 호출하여 잠금을 Monitor.Exit 해제해야 합니다.

Monitor.Wait, Monitor.Pulse, Monitor.PulseAll 메서드를 사용하여 동일한 개체에 대한 잠금을 획득하는 스레드의 상호 작용을 조정할 수 있습니다.

자세한 내용은 API 참조를 Monitor 참조하세요.

비고

클래스를 직접 사용하는 대신 C#의 lock 문과 Visual Basic의 SyncLock 문을 사용하여 Monitor 공유 리소스에 대한 액세스를 동기화합니다. 이러한 문장은 획득된 잠금이 항상 해제되도록 하기 위해 EnterExit 메서드와 try…finally 블록을 사용하여 구현됩니다.

뮤텍스 클래스

System.Threading.Mutex 클래스는 Monitor와 같이 공유 리소스에 대한 단독 액세스 권한을 제공합니다. Mutex.WaitOne 메서드 오버로드 중 하나를 사용하여 뮤텍스의 소유권을 요청합니다. 마찬가지로, MonitorMutex는 스레드 연관성을 갖고 있으며, Mutex.ReleaseMutex 메서드를 호출하여 뮤텍스를 획득한 스레드를 해제해야 합니다.

달리 Monitor클래스는 Mutex 프로세스 간 동기화에 사용할 수 있습니다. 이렇게 하려면 운영 체제 전체에 표시되는 명명된 뮤텍스를 사용합니다. 명명된 뮤텍스 인스턴스를 만들려면 이름을 지정하는 Mutex 생성자를 사용합니다. 메서드를 Mutex.OpenExisting 호출하여 기존의 명명된 시스템 뮤텍스를 열 수도 있습니다.

자세한 내용은 뮤텍스 문서 및 API 참조를 Mutex 참조하세요.

SpinLock 구조체

구조체 System.Threading.SpinLock (예: Monitor잠금의 가용성에 따라 공유 리소스에 대한 단독 액세스 권한 부여). SpinLock 사용할 수 없는 잠금을 획득하려고 하면 루프에서 대기하고 잠금을 사용할 수 있을 때까지 반복적으로 확인합니다.

스핀 잠금 사용의 이점 및 단점에 대한 자세한 내용은 SpinLock 문서 및 API 참조를 SpinLock 참조하세요.

ReaderWriterLockSlim 클래스

클래스는 System.Threading.ReaderWriterLockSlim 쓰기를 위해 공유 리소스에 대한 단독 액세스 권한을 부여하고 여러 스레드가 읽기를 위해 리소스에 동시에 액세스할 수 있도록 합니다. 스레드로부터 안전한 읽기 작업을 지원하지만 쓰기 작업을 수행하려면 단독 액세스가 필요한 공유 데이터 구조에 대한 액세스를 동기화하는 데 사용할 ReaderWriterLockSlim 수 있습니다. 스레드가 독점 접근을 요청하는 경우(예: ReaderWriterLockSlim.EnterWriteLock 메서드를 호출하여) 후속 읽기 요청 및 쓰기 요청은 모든 기존 읽기 요청이 잠금에서 빠져나가고, 쓰기 요청이 잠금에 들어가서 다시 빠져나올 때까지 차단됩니다.

자세한 내용은 API 참조를 ReaderWriterLockSlim 참조하세요.

세마포 및 세마포슬림 클래스

System.Threading.Semaphore 클래스는 System.Threading.SemaphoreSlim 공유 리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한합니다. 리소스를 요청하는 추가 스레드는 스레드가 세마포를 해제할 때까지 대기합니다. 세마포에는 스레드 선호도가 없으므로 스레드는 세마포를 획득할 수 있고 다른 스레드는 세마포를 해제할 수 있습니다.

SemaphoreSlim 는 간단한 대안 Semaphore 이며 단일 프로세스 경계 내의 동기화에만 사용할 수 있습니다.

Windows에서는 프로세스 간 동기화에 사용할 Semaphore 수 있습니다. 이렇게 하려면 이름 또는 Semaphore 메서드를 지정하는 세마포 생성자 중 하나를 사용하여 명명된 시스템 세마포를 나타내는 인스턴스를 만듭니 Semaphore.OpenExisting 다. SemaphoreSlim 는 명명된 시스템 세마포를 지원하지 않습니다.

자세한 내용은 Semaphore 및 SemaphoreSlim 문서와 Semaphore 또는 SemaphoreSlim API 참조를 참조하세요.

스레드 상호 작용 또는 신호

스레드 상호 작용(또는 스레드 신호)은 스레드가 진행하기 위해 하나 이상의 스레드에서 알림 또는 신호를 기다려야 한다는 것을 의미합니다. 예를 들어 스레드 A가 스레드 B의 메서드를 Thread.Join 호출하는 경우 스레드 A는 스레드 B가 완료될 때까지 차단됩니다. 이전 섹션에서 설명한 동기화 기본 형식은 다른 신호 메커니즘을 제공합니다. 잠금을 해제하면 스레드가 잠금을 획득하여 진행할 수 있음을 다른 스레드에 알릴 수 있습니다.

이 섹션에서는 .NET에서 제공하는 추가 신호 구문에 대해 설명합니다.

EventWaitHandle, AutoResetEvent, ManualResetEvent 및 ManualResetEventSlim 클래스

클래스는 System.Threading.EventWaitHandle 스레드 동기화 이벤트를 나타냅니다.

동기화 이벤트는 신호가 없는 상태 또는 신호가 있는 상태일 수 있습니다. 이벤트의 상태가 서명되지 않은 경우 이벤트의 WaitOne 오버로드를 호출하는 스레드는 이벤트가 신호를 보낼 때까지 차단됩니다. 메서드는 EventWaitHandle.Set 이벤트의 상태를 신호로 설정합니다.

신호를 받은 EventWaitHandle 의 동작은 다시 설정 모드에 따라 달라집니다.

Windows에서는 프로세스 간 동기화에 사용할 EventWaitHandle 수 있습니다. 이렇게 하려면 이름 또는 EventWaitHandle 메서드를 지정하는 EventWaitHandle 생성자 중 하나를 사용하여 명명된 시스템 동기화 이벤트를 나타내는 인스턴스를 만듭니 EventWaitHandle.OpenExisting 다.

자세한 내용은 EventWaitHandle 문서를 참조하세요. API 참조는 EventWaitHandle, AutoResetEvent, ManualResetEvent, 및 ManualResetEventSlim를 참조하세요.

CountdownEvent 클래스

클래스는 System.Threading.CountdownEvent 개수가 0일 때 설정되는 이벤트를 나타냅니다. CountdownEvent.CurrentCount가 0보다 큰 동안 CountdownEvent.Wait을 호출하는 스레드는 차단됩니다. 이벤트 수를 줄이도록 호출 CountdownEvent.Signal 합니다.

한 스레드의 신호로 여러 스레드의 차단을 해제하는 데 사용할 수 있는 것과 달리 ManualResetEventManualResetEventSlim여러 스레드의 신호로 하나 이상의 스레드를 차단 해제하는 데 사용할 CountdownEvent 수 있습니다.

자세한 내용은 CountdownEvent 문서 및 API 참조를 CountdownEvent 참조하세요.

Barrier 클래스

클래스는 System.Threading.Barrier 스레드 실행 장벽을 나타냅니다. 메서드를 Barrier.SignalAndWait 호출하는 스레드는 장벽에 도달했음을 알리고 다른 참가자 스레드가 장벽에 도달할 때까지 기다립니다. 모든 참가자 스레드가 장벽에 도달하면 계속 진행되며 장벽이 다시 설정되고 다시 사용할 수 있습니다.

다음 계산 단계로 진행하기 전에 하나 이상의 스레드에 다른 스레드의 결과가 필요할 때 사용할 Barrier 수 있습니다.

자세한 내용은 Barrier 문서 및 API 참조를 Barrier 참조하세요.

Interlocked 클래스 (상호 잠금 클래스)

이 클래스는 System.Threading.Interlocked 변수에 대해 간단한 원자성 연산을 수행하는 정적 메서드를 제공합니다. 이러한 원자성 작업에는 비교에 의존하는 추가, 증가 및 감소, 교환 및 조건부 교환, 64비트 정수 값의 읽기 작업이 포함됩니다.

자세한 내용은 API 참조를 Interlocked 참조하세요.

SpinWait 구조체

이 구조는 System.Threading.SpinWait 스핀 기반 대기를 지원합니다. 스레드가 이벤트 신호를 받거나 조건이 충족될 때까지 기다려야 하지만 실제 대기 시간이 대기 핸들을 사용하거나 스레드를 차단하는 데 필요한 대기 시간보다 낮을 것으로 예상되는 경우 이를 사용할 수 있습니다. 이를 사용하여 SpinWait대기하는 동안 회전할 짧은 기간을 지정한 다음, 지정된 시간에 조건이 충족되지 않은 경우에만 생성(예: 대기 또는 절전 모드)할 수 있습니다.

자세한 내용은 SpinWait 문서 및 API 참조를 SpinWait 참조하세요.

참고하십시오