SemaphoreSlim 클래스
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한하는 Semaphore 대신 사용할 수 있는 간단한 클래스를 나타냅니다.
public ref class SemaphoreSlim : IDisposable
public class SemaphoreSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class SemaphoreSlim : IDisposable
type SemaphoreSlim = class
interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type SemaphoreSlim = class
interface IDisposable
Public Class SemaphoreSlim
Implements IDisposable
- 상속
-
SemaphoreSlim
- 특성
- 구현
예제
다음 예제에서는 최대 스레드 수 3개와 초기 스레드 수가 0인 세마포를 만듭니다. 이 예제에서는 세마포를 기다리는 블록인 5개의 작업을 시작합니다. 주 스레드는 오버로드를 Release(Int32) 호출하여 세마포 수를 최대값으로 늘려 세마포를 입력할 수 있는 세 가지 작업을 허용합니다. 세마포가 해제될 때마다 이전 세마포 수가 표시됩니다. 콘솔 메시지는 세마포 사용을 추적합니다. 출력을 더 쉽게 읽을 수 있도록 각 스레드에 대해 시뮬레이션된 작업 간격이 약간 증가합니다.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
private static SemaphoreSlim semaphore;
// A padding interval to make the output more orderly.
private static int padding;
public static void Main()
{
// Create the semaphore.
semaphore = new SemaphoreSlim(0, 3);
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount);
Task[] tasks = new Task[5];
// Create and start five numbered tasks.
for (int i = 0; i <= 4; i++)
{
tasks[i] = Task.Run(() =>
{
// Each task begins by requesting the semaphore.
Console.WriteLine("Task {0} begins and waits for the semaphore.",
Task.CurrentId);
int semaphoreCount;
semaphore.Wait();
try
{
Interlocked.Add(ref padding, 100);
Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId);
// The task just sleeps for 1+ seconds.
Thread.Sleep(1000 + padding);
}
finally {
semaphoreCount = semaphore.Release();
}
Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
Task.CurrentId, semaphoreCount);
});
}
// Wait for half a second, to allow all the tasks to start and block.
Thread.Sleep(500);
// Restore the semaphore count to its maximum value.
Console.Write("Main thread calls Release(3) --> ");
semaphore.Release(3);
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount);
// Main thread waits for the tasks to complete.
Task.WaitAll(tasks);
Console.WriteLine("Main thread exits.");
}
}
// The example displays output like the following:
// 0 tasks can enter the semaphore.
// Task 1 begins and waits for the semaphore.
// Task 5 begins and waits for the semaphore.
// Task 2 begins and waits for the semaphore.
// Task 4 begins and waits for the semaphore.
// Task 3 begins and waits for the semaphore.
// Main thread calls Release(3) --> 3 tasks can enter the semaphore.
// Task 4 enters the semaphore.
// Task 1 enters the semaphore.
// Task 3 enters the semaphore.
// Task 4 releases the semaphore; previous count: 0.
// Task 2 enters the semaphore.
// Task 1 releases the semaphore; previous count: 0.
// Task 3 releases the semaphore; previous count: 0.
// Task 5 enters the semaphore.
// Task 2 releases the semaphore; previous count: 1.
// Task 5 releases the semaphore; previous count: 2.
// Main thread exits.
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Private semaphore As SemaphoreSlim
' A padding interval to make the output more orderly.
Private padding As Integer
Public Sub Main()
' Create the semaphore.
semaphore = New SemaphoreSlim(0, 3)
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount)
Dim tasks(4) As Task
' Create and start five numbered tasks.
For i As Integer = 0 To 4
tasks(i) = Task.Run(
Sub()
' Each task begins by requesting the semaphore.
Console.WriteLine("Task {0} begins and waits for the semaphore.",
Task.CurrentId)
semaphore.Wait()
Interlocked.Add(padding, 100)
Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId)
' The task just sleeps for 1+ seconds.
Thread.Sleep(1000 + padding)
Console.WriteLine("Task {0} releases the semaphore previous count: {1}.",
Task.CurrentId, semaphore.Release())
End Sub )
Next
' Wait for half a second, to allow all the tasks to start and block.
Thread.Sleep(500)
' Restore the semaphore count to its maximum value.
Console.Write("Main thread calls Release(3) --> ")
semaphore.Release(3)
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount)
' Main thread waits for the tasks to complete.
Task.WaitAll(tasks)
Console.WriteLine("Main thread exits.")
End Sub
End Module
' The example displays output like the following:
' 0 tasks can enter the semaphore.
' Task 1 begins and waits for the semaphore.
' Task 5 begins and waits for the semaphore.
' Task 2 begins and waits for the semaphore.
' Task 4 begins and waits for the semaphore.
' Task 3 begins and waits for the semaphore.
' Main thread calls Release(3) --> 3 tasks can enter the semaphore.
' Task 4 enters the semaphore.
' Task 1 enters the semaphore.
' Task 3 enters the semaphore.
' Task 4 releases the semaphore; previous count: 0.
' Task 2 enters the semaphore.
' Task 1 releases the semaphore; previous count: 0.
' Task 3 releases the semaphore; previous count: 0.
' Task 5 enters the semaphore.
' Task 2 releases the semaphore; previous count: 1.
' Task 5 releases the semaphore; previous count: 2.
' Main thread exits.
설명
세마포는 로컬 세마포와 명명된 시스템 세마포의 두 가지 유형입니다. 로컬 세마포는 애플리케이션에 로컬이고, 시스템 세마포는 운영 체제 전체에 표시되며 프로세스 간 동기화에 적합합니다. Windows SemaphoreSlim 커널 세마포를 사용하지 않는 클래스에 대한 간단한 대안 Semaphore 입니다. 클래스와 Semaphore 달리 클래스는 SemaphoreSlim 명명된 시스템 세마포를 지원하지 않습니다. 로컬 세마포로만 사용할 수 있습니다. 클래스는 SemaphoreSlim 단일 앱 내의 동기화에 권장되는 세마포입니다.
애플리케이션에 로컬 리소스의 풀에 대 한 액세스를 제어 하는 간단한 세마포입니다. 세마포를 인스턴스화할 때 세마포를 동시에 입력할 수 있는 최대 스레드 수를 지정할 수 있습니다. 또한 세마포를 동시에 입력할 수 있는 초기 스레드 수를 지정합니다. 이렇게 하면 세마포의 수가 정의됩니다.
스레드가 세마포에 들어갈 때마다 수가 감소하고 스레드가 세마포를 해제할 때마다 증가합니다. 세마포를 입력하기 위해 스레드는 오버로드 중 Wait WaitAsync 하나를 호출합니다. 세마포를 해제하려면 오버로드 중 Release 하나를 호출합니다. 개수가 0에 도달하면 다른 스레드가 세마포를 Wait
해제할 때까지 메서드 블록 중 하나를 호출합니다. 여러 스레드가 차단되는 경우 스레드가 세마포에 들어갈 때를 제어하는 FIFO 또는 LIFO와 같은 보장된 순서는 없습니다.
세마포를 사용하여 리소스를 보호하는 코드의 기본 구조는 다음과 같습니다.
' Enter semaphore by calling one of the Wait or WaitAsync methods.
SemaphoreSlim.Wait()
'
' Execute code protected by the semaphore.
'
SemaphoreSlim.Release()
모든 스레드가 세마포를 해제하면 세마포가 생성될 때 지정된 최대값으로 계산됩니다. 세마포의 개수는 속성에서 CurrentCount 사용할 수 있습니다.
중요
클래스는 SemaphoreSlim , WaitAsync및 Release 메서드 호출에 스레드 또는 작업 ID를 Wait적용하지 않습니다. 또한 생성자를 사용하여 개체 CurrentCount 를 인스턴스화하는 SemaphoreSlim 경우 SemaphoreSlim(Int32) 생성자가 설정한 값 이상으로 속성을 늘릴 수 있습니다. 프로그래머의 책임은 메서드 호출 또는 메서드 호출 Wait 과 적절히 결합되도록 하는 것입니다Release.WaitAsync
생성자
SemaphoreSlim(Int32) |
동시에 부여할 수 있는 초기 요청 수를 지정하여 SemaphoreSlim 클래스의 새 인스턴스를 초기화합니다. |
SemaphoreSlim(Int32, Int32) |
동시에 부여할 수 있는 초기 및 최대 요청 수를 지정하여 SemaphoreSlim 클래스의 새 인스턴스를 초기화합니다. |
속성
AvailableWaitHandle |
세마포에서 대기하는 데 사용할 수 있는 WaitHandle을(를) 반환합니다. |
CurrentCount |
SemaphoreSlim 개체에 들어갈 수 있는 남아 있는 스레드의 수를 가져옵니다. |
메서드
Dispose() |
SemaphoreSlim 클래스의 현재 인스턴스에서 사용하는 모든 리소스를 해제합니다. |
Dispose(Boolean) |
SemaphoreSlim에서 사용하는 관리되지 않는 리소스를 해제하고, 관리되는 리소스를 선택적으로 해제할 수 있습니다. |
Equals(Object) |
지정된 개체가 현재 개체와 같은지 확인합니다. (다음에서 상속됨 Object) |
GetHashCode() |
기본 해시 함수로 작동합니다. (다음에서 상속됨 Object) |
GetType() |
현재 인스턴스의 Type을 가져옵니다. (다음에서 상속됨 Object) |
MemberwiseClone() |
현재 Object의 단순 복사본을 만듭니다. (다음에서 상속됨 Object) |
Release() |
SemaphoreSlim 개체를 한 번 해제합니다. |
Release(Int32) |
SemaphoreSlim 개체를 지정된 횟수만큼 해제합니다. |
ToString() |
현재 개체를 나타내는 문자열을 반환합니다. (다음에서 상속됨 Object) |
Wait() |
현재 스레드가 SemaphoreSlim에 진입할 수 있을 때까지 스레드를 차단합니다. |
Wait(CancellationToken) |
SemaphoreSlim을 확인하면서 현재 스레드가 CancellationToken에 진입할 수 있을 때까지 스레드를 차단합니다. |
Wait(Int32) |
시간 제한을 지정하는 부호 있는 32비트 정수를 사용하여 현재 스레드가 SemaphoreSlim에 진입할 수 있을 때까지 스레드를 차단합니다. |
Wait(Int32, CancellationToken) |
SemaphoreSlim을 확인하면서 시간 제한을 지정하는 부호 있는 32비트 정수를 사용하여 현재 스레드가 CancellationToken에 진입할 수 있을 때까지 스레드를 차단합니다. |
Wait(TimeSpan) |
SemaphoreSlim으로 시간 제한을 지정하여 현재 스레드가 TimeSpan에 진입할 수 있을 때까지 스레드를 차단합니다. |
Wait(TimeSpan, CancellationToken) |
SemaphoreSlim을 확인하면서 시간 제한을 지정하는 TimeSpan을 사용하여 현재 스레드가 CancellationToken에 진입할 수 있을 때까지 스레드를 차단합니다. |
WaitAsync() |
SemaphoreSlim으로 전환될 때까지 비동기적으로 기다립니다. |
WaitAsync(CancellationToken) |
SemaphoreSlim을 관찰하는 동안 CancellationToken으로 전환될 때까지 비동기적으로 기다립니다. |
WaitAsync(Int32) |
32비트 부호 있는 정수를 사용하여 시간 간격을 측정하여 SemaphoreSlim으로 전환될 때까지 비동기적으로 기다립니다. |
WaitAsync(Int32, CancellationToken) |
SemaphoreSlim을 관찰하는 동안 32비트 부호 있는 정수를 사용하여 시간 간격을 측정하여 CancellationToken으로 전환될 때까지 비동기적으로 기다립니다. |
WaitAsync(TimeSpan) |
SemaphoreSlim을 사용하여 시간 간격을 측정하여 TimeSpan으로 전환될 때까지 비동기적으로 기다립니다. |
WaitAsync(TimeSpan, CancellationToken) |
SemaphoreSlim을 관찰하는 동안 TimeSpan을 사용하여 시간 간격을 측정하여 CancellationToken으로 전환될 때까지 비동기적으로 기다립니다. |
적용 대상
스레드 보안
모든 공용 및 보호된 멤버 SemaphoreSlim 는 스레드로부터 안전하며 여러 스레드에서 동시에 사용될 수 있습니다. 단 Dispose(), 다른 모든 작업이 SemaphoreSlim 완료된 경우에만 사용해야 합니다.