동기화 기본 형식 개요Overview of synchronization primitives

.NET은 공유 리소스에 대한 액세스를 동기화하거나 스레드 상호 작용을 조정하는 데 사용할 수 있는 다양한 형식을 제공합니다..NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

중요

동일한 동기화 기본 형식 인스턴스를 사용하여 공유 리소스에 대한 액세스를 보호합니다.Use the same synchronization primitive instance to protect access of a shared resource. 다른 동기화 기본 형식 인스턴스를 사용하여 동일한 리소스를 보호하는 경우 동기화 기본 형식에서 제공하는 보호를 사용할 수 없게 됩니다.If you use different synchronization primitive instances to protect the same resource, you'll circumvent the protection provided by a synchronization primitive.

WaitHandle 클래스 및 간단한 동기화 형식WaitHandle class and lightweight synchronization types

여러 .NET 동기화 기본 형식이 System.Threading.WaitHandle 클래스에서 파생됩니다. 이 클래스는 네이티브 운영 체제 동기화 핸들을 캡슐화하고 스레드 상호 작용의 신호 메커니즘을 사용합니다.Multiple .NET synchronization primitives derive from the System.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. 해당 클래스에는 다음이 포함됩니다.Those classes include:

  • System.Threading.Mutex - 공유 리소스에 대한 배타적 액세스 권한을 부여합니다.System.Threading.Mutex, which grants exclusive access to a shared resource. 뮤텍스의 상태는 스레드가 소유하지 않는 경우 신호를 받습니다.The state of a mutex is signaled if no thread owns it.
  • System.Threading.Semaphore - 공유 리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한합니다.System.Threading.Semaphore, which limits the number of threads that can access a shared resource or a pool of resources concurrently. 세마포 상태는 해당 개수가 0보다 크면 신호 알림으로 설정되고 해당 개수가 0이면 신호 알림 해제로 설정됩니다.The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.
  • System.Threading.EventWaitHandle - 스레드 동기화 이벤트를 나타내고 신호 알림 또는 신호 알림 해제 상태일 수 있습니다.System.Threading.EventWaitHandle, which represents a thread synchronization event and can be either in a signaled or unsignaled state.
  • System.Threading.AutoResetEvent - EventWaitHandle에서 파생되고 신호 알림을 받으면 단일 대기 스레드를 해제한 후 자동으로 신호 알림 해제 상태로 다시 설정됩니다.System.Threading.AutoResetEvent, which derives from EventWaitHandle and, when signaled, resets automatically to an unsignaled state after releasing a single waiting thread.
  • System.Threading.ManualResetEvent - EventWaitHandle에서 파생되고 신호 알림을 받을 경우 Reset 메서드가 호출될 때까지 신호 알림 상태를 유지합니다.System.Threading.ManualResetEvent, which derives from EventWaitHandle and, when signaled, stays in a signaled state until the Reset method is called.

.NET Framework에서 WaitHandleSystem.MarshalByRefObject에서 파생되므로 대기 핸들을 사용하여 애플리케이션 도메인 경계에 걸쳐 스레드 활동을 동기화할 수 있습니다.In the .NET Framework, because WaitHandle derives from System.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

.NET Framework 및 .NET Core에서 이러한 형식 중 일부는 운영 체제 전체에 표시되고 프로세스 간 동기화에 사용할 수 있는 명명된 시스템 동기화 핸들을 나타낼 수 있습니다.In the .NET Framework and .NET Core, some of these types can represent named system synchronization handles, which are visible throughout the operating system and can be used for the inter-process synchronization:

  • Mutex(.NET Framework 및 .NET Core),Mutex (.NET Framework and .NET Core),
  • Semaphore(Windows의 .NET Framework 및 .NET Core),Semaphore (.NET Framework and .NET Core on Windows),
  • EventWaitHandle(Windows의 .NET Framework 및 .NET Core).EventWaitHandle (.NET Framework and .NET Core on Windows).

자세한 내용은 WaitHandle API 참조를 참조하세요.For more information, see the WaitHandle API reference.

간단한 동기화 형식은 기본 운영 체제 핸들을 사용하지 않고 일반적으로 향상된 성능을 제공합니다.Lightweight synchronization types don't rely on underlying operating system handles and typically provide better performance. 그러나 프로세스 간 동기화에는 사용할 수 없습니다.However, they cannot be used for the inter-process synchronization. 한 애플리케이션 내에서 이러한 형식의 스레드 동기화를 사용합니다.Use those types for thread synchronization within one application.

이러한 형식 중 일부는 WaitHandle에서 파생된 형식의 대체 항목입니다.Some of those types are alternatives to the types derived from WaitHandle. 예를 들어 SemaphoreSlimSemaphore의 간단한 대체 항목입니다.For example, SemaphoreSlim is a lightweight alternative to Semaphore.

공유 리소스에 대한 액세스 동기화Synchronization of access to a shared resource

.NET은 여러 스레드가 공유 리소스에 대한 액세스를 제어할 수 있는 다양한 동기화 기본 형식을 제공합니다..NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Monitor 클래스Monitor class

System.Threading.Monitor 클래스는 리소스를 식별하는 개체에 대한 잠금을 획득하거나 해제하여 공유 리소스에 대한 상호 배타적 액세스 권한을 부여합니다.The System.Threading.Monitor class grants mutually exclusive access to a shared resource by acquiring or releasing a lock on the object that identifies the resource. 잠금이 유지되는 동안 잠금을 보유하는 스레드는 잠금을 다시 획득하고 해제할 수 있습니다.While a lock is held, the thread that holds the lock can again acquire and release the lock. 다른 스레드는 잠금을 획득할 수 없도록 차단되고 Monitor.Enter 메서드는 잠금이 해제될 때까지 대기합니다.Any other thread is blocked from acquiring the lock and the Monitor.Enter method waits until the lock is released. Enter 메서드는 해제된 잠금을 획득합니다.The Enter method acquires a released lock. 또한 Monitor.TryEnter 메서드를 사용하여 스레드가 잠금을 획득하려고 시도하는 시간을 지정할 수도 있습니다.You can also use the Monitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. Monitor 클래스에 스레드 선호도가 있으므로 잠금을 획득한 스레드는 Monitor.Exit 메서드를 호출하여 잠금을 해제해야 합니다.Because the Monitor class has thread affinity, the thread that acquired a lock must release the lock by calling the Monitor.Exit method.

Monitor.Wait, Monitor.PulseMonitor.PulseAll 메서드를 사용하여 동일한 개체에 대한 잠금을 획득하는 스레드의 상호 작용을 조정할 수 있습니다.You can coordinate the interaction of threads that acquire a lock on the same object by using the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

자세한 내용은 Monitor API 참조를 참조하세요.For more information, see the Monitor API reference.

참고

Monitor 클래스를 직접 사용하는 대신 C#의 lock 문 및 Visual Basic의 SyncLock 문을 사용하여 공유 리소스에 대한 액세스를 동기화합니다.Use the lock statement in C# and the SyncLock statement in Visual Basic to synchronize access to a shared resource instead of using the Monitor class directly. 이러한 문은 획득한 잠금이 항상 해제되도록 EnterExit 메서드와 try…finally 블록을 사용하여 구현됩니다.Those statements are implemented by using the Enter and Exit methods and a try…finally block to ensure that the acquired lock is always released.

Mutex 클래스Mutex class

Monitor와 같은 System.Threading.Mutex 클래스는 공유 리소스에 대한 배타적 액세스 권한을 부여합니다.The System.Threading.Mutex class, like Monitor, grants exclusive access to a shared resource. Mutex.WaitOne 메서드 오버로드 중 하나를 사용하여 뮤텍스의 소유권을 요청합니다.Use one of the Mutex.WaitOne method overloads to request the ownership of a mutex. Monitor와 마찬가지로 Mutex에는 스레드 선호도가 있고 뮤텍스를 획득한 스레드는 Mutex.ReleaseMutex 메서드를 호출하여 뮤텍스를 해제해야 합니다.Like Monitor, Mutex has thread affinity and the thread that acquired a mutex must release it by calling the Mutex.ReleaseMutex method.

Monitor와 달리 Mutex 클래스는 프로세스 간 동기화에 사용할 수 있습니다.Unlike Monitor, the Mutex class can be used for inter-process synchronization. 이를 수행하려면 운영 체제 전체에 표시되는 명명된 뮤텍스를 사용합니다.To do that, use a named mutex, which is visible throughout the operating system. 명명된 뮤텍스 인스턴스를 만들려면 이름을 지정하는 뮤텍스 생성자를 사용합니다.To create a named mutex instance, use a Mutex constructor that specifies a name. Mutex.OpenExisting 메서드를 호출하여 기존 명명된 시스템 뮤텍스를 열 수도 있습니다.You also can call the Mutex.OpenExisting method to open an existing named system mutex.

자세한 내용은 뮤텍스 문서 및 Mutex API 참조를 참조하세요.For more information, see the Mutexes article and the Mutex API reference.

SpinLock 구조체SpinLock structure

Monitor와 같은 System.Threading.SpinLock 구조체는 잠금의 가용성에 따라 공유 리소스에 대한 배타적 액세스 권한을 부여합니다.The System.Threading.SpinLock structure, like Monitor, grants exclusive access to a shared resource based on the availability of a lock. SpinLock이 사용할 수 없는 잠금을 획득하려고 하면 잠금을 사용할 수 있을 때까지 루프에서 반복적으로 확인하면서 대기합니다.When SpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

회전 잠금을 사용하는 이점 및 결점에 대한 자세한 내용은 SpinLock 문서 및 SpinLock API 참조를 참조하세요.For more information about the benefits and drawbacks of using spin lock, see the SpinLock article and the SpinLock API reference.

ReaderWriterLockSlim 클래스ReaderWriterLockSlim class

System.Threading.ReaderWriterLockSlim 클래스는 쓰기 위해 공유 리소스에 대한 배타적 액세스 권한을 부여하고, 읽기 위해 여러 스레드가 동시에 리소스에 액세스하도록 허용합니다.The System.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. ReaderWriterLockSlim을 사용하여 스레드로부터 안전한 읽기 작업을 지원하지만 쓰기 작업을 수행할 배타적 액세스 권한이 필요한 공유 데이터 구조에 대한 액세스를 동기화할 수 있습니다.You might want to use ReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. 스레드가 배타적 액세스를 요청하면(예: ReaderWriterLockSlim.EnterWriteLock 메서드 호출을 통해) 모든 기존 판독기가 잠금을 종료하고 작성기가 잠금을 시작 및 종료할 때까지 후속 판독기 및 작성기 요청이 차단됩니다.When a thread requests exclusive access (for example, by calling the ReaderWriterLockSlim.EnterWriteLock method), subsequent reader and writer requests block until all existing readers have exited the lock, and the writer has entered and exited the lock.

자세한 내용은 ReaderWriterLockSlim API 참조를 참조하세요.For more information, see the ReaderWriterLockSlim API reference.

세마포 및 SemaphoreSlim 클래스Semaphore and SemaphoreSlim classes

System.Threading.SemaphoreSystem.Threading.SemaphoreSlim 클래스는 공유 리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한합니다.The System.Threading.Semaphore and System.Threading.SemaphoreSlim classes limit the number of threads that can access a shared resource or a pool of resources concurrently. 리소스를 요청하는 추가적인 스레드는 스레드가 세마포를 해제할 때까지 대기합니다.Additional threads that request the resource wait until any thread releases the semaphore. 세마포에는 스레드 선호도가 없으므로 한 스레드가 세마포를 획득할 수 있고 또 다른 스레드가 해당 세마포를 해제할 수 있습니다.Because the semaphore doesn't have thread affinity, a thread can acquire the semaphore and another one can release it.

SemaphoreSlimSemaphore의 간단한 대체 항목이고 단일 프로세스 경계 내의 동기화에만 사용할 수 있습니다.SemaphoreSlim is a lightweight alternative to Semaphore and can be used only for synchronization within a single process boundary.

Windows에서는 프로세스 간 동기화에 Semaphore를 사용할 수 있습니다.On Windows, you can use Semaphore for the inter-process synchronization. 이 작업을 수행하려면 이름을 지정하는 Semaphore세마포 생성자 중 하나 또는 메서드를 사용하여 명명된 시스템 세마포를 나타내는 Semaphore.OpenExisting 인스턴스를 만듭니다.To do that, create a Semaphore instance that represents a named system semaphore by using one of the Semaphore constructors that specifies a name or the Semaphore.OpenExisting method. SemaphoreSlim은 명명된 시스템 세마포를 지원하지 않습니다.SemaphoreSlim doesn't support named system semaphores.

자세한 내용은 세마포 및 SemaphoreSlim 문서와 Semaphore 또는 SemaphoreSlim API 참조를 참조하세요.For more information, see the Semaphore and SemaphoreSlim article and the Semaphore or SemaphoreSlim API reference.

스레드 상호 작용 또는 신호Thread interaction, or signaling

스레드 상호 작용(또는 스레드 신호)은 스레드가 계속 진행하기 위해 하나 이상의 스레드에서 알림이나 신호를 기다려야 함을 의미합니다.Thread interaction (or thread signaling) means that a thread must wait for notification, or a signal, from one or more threads in order to proceed. 예를 들어 스레드 A가 스레드 B의 Thread.Join 메서드를 호출하는 경우 스레드 B가 완료될 때까지 스레드 A가 차단됩니다.For example, if thread A calls the Thread.Join method of thread B, thread A is blocked until thread B completes. 이전 섹션에 설명된 동기화 기본 형식은 신호를 위한 다른 메커니즘을 제공합니다. 잠금을 해제함으로써 스레드는 또 다른 스레드에 잠금을 획득하면 계속 진행할 수 있음을 알립니다.The synchronization primitives described in the preceding section provide a different mechanism for signaling: by releasing a lock, a thread notifies another thread that it can proceed by acquiring the lock.

이 섹션에서는 .NET에서 제공하는 추가 신호 구문을 설명합니다.This section describes additional signaling constructs provided by .NET.

EventWaitHandle, AutoResetEvent, ManualResetEvent 및 ManualResetEventSlim 클래스EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

System.Threading.EventWaitHandle 클래스는 스레드 동기화 이벤트를 나타냅니다.The System.Threading.EventWaitHandle class represents a thread synchronization event.

동기화 이벤트는 신호 알림 또는 신호 알림 해제 상태일 수 있습니다.A synchronization event can be either in an unsignaled or signaled state. 이벤트 상태가 신호 알림 해제인 경우 이벤트의 WaitOne 오버로드를 호출하는 스레드는 이벤트가 신호 알림을 받을 때까지 차단됩니다.When the state of an event is unsignaled, a thread that calls the event's WaitOne overload is blocked until an event is signaled. EventWaitHandle.Set 메서드는 이벤트 상태를 신호 알림으로 설정합니다.The EventWaitHandle.Set method sets the state of an event to signaled.

신호 알림을 받은 EventWaitHandle의 동작은 재설정 모드에 따라 다릅니다.The behavior of an EventWaitHandle that has been signaled depends on its reset mode:

Windows에서는 프로세스 간 동기화에 EventWaitHandle를 사용할 수 있습니다.On Windows, you can use EventWaitHandle for the inter-process synchronization. 이 작업을 수행하려면 이름을 지정하는 EventWaitHandleEventWaitHandle 생성자 중 하나 또는 메서드를 사용하여 명명된 시스템 동기화 이벤트를 나타내는 EventWaitHandle.OpenExisting 인스턴스를 만듭니다.To do that, create a EventWaitHandle instance that represents a named system synchronization event by using one of the EventWaitHandle constructors that specifies a name or the EventWaitHandle.OpenExisting method.

자세한 내용은 EventWaitHandle 문서를 참조하세요.For more information, see the EventWaitHandle article. API 참조에 대해서는 EventWaitHandle, AutoResetEvent, ManualResetEventManualResetEventSlim을 참조하세요.For the API reference, see EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim.

CountdownEvent 클래스CountdownEvent class

System.Threading.CountdownEvent 클래스는 개수가 0일 때 설정되는 이벤트를 나타냅니다.The System.Threading.CountdownEvent class represents an event that becomes set when its count is zero. CountdownEvent.CurrentCount는 0보다 크지만 CountdownEvent.Wait를 호출하는 스레드가 차단됩니다.While CountdownEvent.CurrentCount is greater than zero, a thread that calls CountdownEvent.Wait is blocked. CountdownEvent.Signal을 호출하여 이벤트의 수를 감소시킵니다.Call CountdownEvent.Signal to decrement an event's count.

한 스레드의 신호로 다중 스레드를 차단 해제하는 데 사용할 수 있는 ManualResetEvent 또는 ManualResetEventSlim와 달리, CountdownEvent를 사용하여 여러 스레드의 신호로 하나 이상의 스레드를 차단 해제할 수 있습니다.In contrast to ManualResetEvent or ManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can use CountdownEvent to unblock one or more threads with signals from multiple threads.

자세한 내용은 CountdownEvent 문서 및 CountdownEvent API 참조를 참조하세요.For more information, see the CountdownEvent article and the CountdownEvent API reference.

Barrier 클래스Barrier class

System.Threading.Barrier 클래스는 스레드 실행 경계를 나타냅니다.The System.Threading.Barrier class represents a thread execution barrier. Barrier.SignalAndWait 메서드를 호출하는 스레드는 장벽에 도달했다는 신호 알림을 보내고 다른 참가자 스레드가 경계에 도달할 때까지 대기합니다.A thread that calls the Barrier.SignalAndWait method signals that it reached the barrier and waits until other participant threads reach the barrier. 모든 참가자 스레드는 장벽에 도달하면 계속 진행하며 장벽이 다시 설정되고 다시 사용할 수 있습니다.When all participant threads reach the barrier, they proceed and the barrier is reset and can be used again.

하나 이상의 스레드가 다음 계산 단계로 진행하기 전에 다른 스레드의 결과를 필요로 할 때 Barrier를 사용할 수 있습니다.You might use Barrier when one or more threads require the results of other threads before proceeding to the next computation phase.

자세한 내용은 Barrier 문서 및 Barrier API 참조를 참조하세요.For more information, see the Barrier article and the Barrier API reference.

Interlocked 클래스Interlocked class

System.Threading.Interlocked 클래스는 변수에서 단순 원자성 작업을 수행하는 정적 메서드를 제공합니다.The System.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. 해당 원자성 작업에는 비교에 따른 추가, 증가 및 감소, 교환, 조건부 교환이 포함되고 64비트 정수 값을 읽는 작업이 포함됩니다.Those atomic operations include addition, increment and decrement, exchange and conditional exchange that depends on a comparison, and read operation of a 64-bit integer value.

자세한 내용은 Interlocked API 참조를 참조하세요.For more information, see the Interlocked API reference.

SpinWait 구조체SpinWait structure

System.Threading.SpinWait 구조체는 회전 기반 대기를 지원합니다.The System.Threading.SpinWait structure provides support for spin-based waiting. 이벤트가 신호를 받거나 조건이 충족될 때까지 스레드가 대기해야 하지만 대기 핸들을 사용하거나 현재 스레드를 차단하여 실제 대기 시간이 필요한 대기 시간보다 적을 것으로 예상할 때 이를 사용할 수 있습니다.You might want to use it when a thread has to wait for an event to be signaled or a condition to be met, but when the actual wait time is expected to be less than the waiting time required by using a wait handle or by otherwise blocking the thread. SpinWait를 사용하면 대기하는 동안 스핀하고 지정된 시간 안에 조건이 충족되지 않을 경우에만 대기 또는 중지를 통해 양보하는 짧은 기간을 지정할 수 있습니다.By using SpinWait, you can specify a short period of time to spin while waiting, and then yield (for example, by waiting or sleeping) only if the condition was not met in the specified time.

자세한 내용은 SpinWait 문서 및 SpinWait API 참조를 참조하세요.For more information, see the SpinWait article and the SpinWait API reference.

참고 항목See also