다음을 통해 공유


세마포 및 세마포슬림

클래스는 System.Threading.Semaphore 명명된(시스템 전체) 또는 로컬 세마포를 나타냅니다. Win32 세마포 객체를 감싸고 있는 경량 래퍼입니다. Win32 세마포는 카운팅 세마포로, 리소스 풀에 대한 액세스를 제어하는 데 사용할 수 있습니다.

이 클래스는 SemaphoreSlim 대기 시간이 매우 짧을 것으로 예상되는 경우 단일 프로세스 내에서 대기하는 데 사용할 수 있는 가볍고 빠른 세마포를 나타냅니다. SemaphoreSlim 는 CLR(공용 언어 런타임)에서 제공하는 동기화 기본 형식에 최대한 많이 의존합니다. 그러나 필요에 따라 지연 초기화된 커널 기반 대기 핸들을 제공하여 여러 세마포 대기를 지원합니다. SemaphoreSlim 또한 취소 토큰의 사용을 지원하지만 명명된 세마포 또는 동기화를 위한 대기 핸들 사용을 지원하지 않습니다.

제한된 리소스 관리

스레드가 세마포어에 진입하려면 WaitOne 객체의 경우 WaitHandle 메서드를 호출하고, System.Threading.Semaphore 객체의 경우 SemaphoreSlim.Wait 또는 SemaphoreSlim.WaitAsync 메서드를 호출합니다. 이들은 각각 SemaphoreSlim 클래스에서 상속된 메서드입니다. 호출이 반환될 때, 세마포어의 카운트가 감소합니다. 스레드가 항목을 요청하고 개수가 0이면 스레드가 차단됩니다. 스레드가 Semaphore.Release 또는 SemaphoreSlim.Release 메서드를 호출하여 세마포를 해제하면, 차단된 스레드는 들어갈 수 있습니다. 차단된 스레드가 세마포에 진입하기 위해 선입선출(FIFO) 또는 후입선출(LIFO)과 같은 보장된 순서는 없습니다.

스레드는 System.Threading.Semaphore 개체의 WaitOne 메서드나 SemaphoreSlim 개체의 Wait 메서드를 반복적으로 호출하여 세마포를 여러 번 입력할 수 있습니다. 세마포를 해제하기 위해 스레드는 동일한 횟수의 메서드 오버로드를 호출 Semaphore.Release() 하거나 SemaphoreSlim.Release() 또는 Semaphore.Release(Int32) 메서드 오버로드를 호출 SemaphoreSlim.Release(Int32) 하고 해제할 항목 수를 지정할 수 있습니다.

세마포 및 스레드 ID

두 세마포 형식은 , WaitOneWaitRelease 메서드 호출에 스레드 ID를 SemaphoreSlim.Release적용하지 않습니다. 예를 들어 세마포에 대한 일반적인 사용 시나리오에는 생산자 스레드와 소비자 스레드가 포함되며, 한 스레드는 항상 세마포 수를 증가시키고 다른 스레드는 항상 감소합니다.

스레드가 세마포를 너무 많이 해제하지 않도록 하는 것은 프로그래머의 책임입니다. 예를 들어 세마포의 최대 개수는 2이고 스레드 A와 스레드 B는 모두 세마포를 입력한다고 가정합니다. 스레드 B의 프로그래밍 오류로 인해 두 번 호출 Release 되면 두 호출 모두 성공합니다. 세마포의 개수가 꽉 찼고, 스레드 A가 Release를 호출하면 SemaphoreFullException가 발생합니다.

이름이 지정된 세마포

Windows 운영 체제에서는 세마포에 이름이 있을 수 있습니다. 명명된 세마포는 시스템 전체에 걸쳐 작동합니다. 즉, 명명된 세마포가 만들어지면 모든 프로세스의 모든 스레드에 표시됩니다. 따라서 명명된 세마포를 사용하여 프로세스의 활동과 스레드를 동기화할 수 있습니다.

이름을 지정하는 생성자 중 하나를 사용하여 명명된 시스템 세마포를 나타내는 개체를 만들 Semaphore 수 있습니다.

비고

명명된 세마포는 시스템 전체이므로 동일한 명명된 세마포를 나타내는 여러 Semaphore 개체를 가질 수 있습니다. 생성자 또는 메서드를 호출할 Semaphore.OpenExisting 때마다 새 Semaphore 개체가 만들어집니다. 동일한 이름을 반복적으로 지정하면 동일한 명명된 세마포를 나타내는 여러 개체가 만들어집니다.

명명된 세마포를 사용할 때는 주의해야 합니다. 시스템 전반에 걸쳐 있기 때문에, 동일한 이름을 사용하는 다른 프로세스에서 예상치 못하게 세마포어에 진입할 수 있습니다. 동일한 컴퓨터에서 실행되는 악성 코드는 서비스 거부 공격의 기초로 사용할 수 있습니다.

액세스 제어 보안을 사용하여 명명된 세마포를 나타내는 Semaphore 개체를 보호하세요. 이때, System.Security.AccessControl.SemaphoreSecurity 개체를 지정하는 생성자를 사용하는 것이 좋습니다. 이 방법을 사용하여 Semaphore.SetAccessControl 액세스 제어 보안을 적용할 수도 있지만 세마포가 만들어진 시간과 보호되는 시간 사이에 취약성의 창이 남습니다. 액세스 제어 보안으로 세마포를 보호하면 악의적인 공격을 방지하는 데 도움이 되지만 의도하지 않은 이름 충돌 문제를 해결하지는 못합니다.

참고하십시오