Semaphore 클래스

정의

리소스 또는 리소스 풀에 동시에 액세스할 수 있는 스레드 수를 제한합니다.

public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
상속
Semaphore
상속
특성

예제

다음 코드 예제에서는 최대 개수가 3이고 초기 개수가 0인 세마포를 만듭니다. 이 예제에서는 세마포 대기를 차단하는 5개의 스레드를 시작합니다. 기본 스레드는 메서드 오버로드를 사용하여 Release(Int32) 세마포 수를 최대값으로 늘려 3개의 스레드가 세마포에 들어갈 수 있도록 합니다. 각 스레드는 메서드를 Thread.Sleep 사용하여 1초 동안 기다렸다가 작업을 시뮬레이션한 다음 메서드 오버로드를 호출 Release() 하여 세마포를 해제합니다. 세마포가 해제될 때마다 이전 세마포 수가 표시됩니다. 콘솔 메시지는 세마포 사용을 추적합니다. 출력을 더 쉽게 읽을 수 있도록 각 스레드에 대해 시뮬레이션된 작업 간격이 약간 증가합니다.

#using <System.dll>
using namespace System;
using namespace System::Threading;

public ref class Example
{
private:
   // A semaphore that simulates a limited resource pool.
   //
   static Semaphore^ _pool;

   // A padding interval to make the output more orderly.
   static int _padding;

public:
   static void Main()
   {
      // Create a semaphore that can satisfy up to three
      // concurrent requests. Use an initial count of zero,
      // so that the entire semaphore count is initially
      // owned by the main program thread.
      //
      _pool = gcnew Semaphore( 0,3 );
      
      // Create and start five numbered threads.
      //
      for ( int i = 1; i <= 5; i++ )
      {
         Thread^ t = gcnew Thread(
            gcnew ParameterizedThreadStart( Worker ) );
         
         // Start the thread, passing the number.
         //
         t->Start( i );
      }
      
      // Wait for half a second, to allow all the
      // threads to start and to block on the semaphore.
      //
      Thread::Sleep( 500 );
      
      // The main thread starts out holding the entire
      // semaphore count. Calling Release(3) brings the
      // semaphore count back to its maximum value, and
      // allows the waiting threads to enter the semaphore,
      // up to three at a time.
      //
      Console::WriteLine( L"Main thread calls Release(3)." );
      _pool->Release( 3 );

      Console::WriteLine( L"Main thread exits." );
   }

private:
   static void Worker( Object^ num )
   {
      // Each worker thread begins by requesting the
      // semaphore.
      Console::WriteLine( L"Thread {0} begins and waits for the semaphore.", num );
      _pool->WaitOne();
      
      // A padding interval to make the output more orderly.
      int padding = Interlocked::Add( _padding, 100 );

      Console::WriteLine( L"Thread {0} enters the semaphore.", num );
      
      // The thread's "work" consists of sleeping for
      // about a second. Each thread "works" a little
      // longer, just to make the output more orderly.
      //
      Thread::Sleep( 1000 + padding );

      Console::WriteLine( L"Thread {0} releases the semaphore.", num );
      Console::WriteLine( L"Thread {0} previous semaphore count: {1}",
         num, _pool->Release() );
   }
};
using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _pool = new Semaphore(initialCount: 0, maximumCount: 3);

        // Create and start five numbered threads. 
        //
        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        //
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(releaseCount: 3);

        Console.WriteLine("Main thread exits.");
    }

    private static void Worker(object num)
    {
        // Each worker thread begins by requesting the
        // semaphore.
        Console.WriteLine("Thread {0} begins " +
            "and waits for the semaphore.", num);
        _pool.WaitOne();

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
Imports System.Threading

Public Class Example

    ' A semaphore that simulates a limited resource pool.
    '
    Private Shared _pool As Semaphore

    ' A padding interval to make the output more orderly.
    Private Shared _padding As Integer

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a semaphore that can satisfy up to three
        ' concurrent requests. Use an initial count of zero,
        ' so that the entire semaphore count is initially
        ' owned by the main program thread.
        '
        _pool = New Semaphore(0, 3)

        ' Create and start five numbered threads. 
        '
        For i As Integer = 1 To 5
            Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
            'Dim t As New Thread(AddressOf Worker)

            ' Start the thread, passing the number.
            '
            t.Start(i)
        Next i

        ' Wait for half a second, to allow all the
        ' threads to start and to block on the semaphore.
        '
        Thread.Sleep(500)

        ' The main thread starts out holding the entire
        ' semaphore count. Calling Release(3) brings the 
        ' semaphore count back to its maximum value, and
        ' allows the waiting threads to enter the semaphore,
        ' up to three at a time.
        '
        Console.WriteLine("Main thread calls Release(3).")
        _pool.Release(3)

        Console.WriteLine("Main thread exits.")
    End Sub

    Private Shared Sub Worker(ByVal num As Object)
        ' Each worker thread begins by requesting the
        ' semaphore.
        Console.WriteLine("Thread {0} begins " _
            & "and waits for the semaphore.", num)
        _pool.WaitOne()

        ' A padding interval to make the output more orderly.
        Dim padding As Integer = Interlocked.Add(_padding, 100)

        Console.WriteLine("Thread {0} enters the semaphore.", num)
        
        ' The thread's "work" consists of sleeping for 
        ' about a second. Each thread "works" a little 
        ' longer, just to make the output more orderly.
        '
        Thread.Sleep(1000 + padding)

        Console.WriteLine("Thread {0} releases the semaphore.", num)
        Console.WriteLine("Thread {0} previous semaphore count: {1}", _
            num, _
            _pool.Release())
    End Sub
End Class

설명

클래스를 Semaphore 사용하여 리소스 풀에 대한 액세스를 제어합니다. 스레드는 클래스에서 상속되는 메서드를 WaitOne 호출하여 세마포를 WaitHandle 입력하고 메서드를 호출하여 세마포를 Release 해제합니다.

스레드가 세마포에 들어갈 때마다 세마포의 수가 감소하고 스레드가 세마포를 해제할 때 증가합니다. 개수가 0이면 다른 스레드가 세마포를 해제할 때까지 후속 요청이 차단됩니다. 모든 스레드가 세마포를 해제한 경우 세마포를 만들 때 개수가 지정된 최대값입니다.

차단된 스레드가 세마포로 들어가는 FIFO 또는 LIFO와 같은 보장된 순서는 없습니다.

스레드는 메서드를 반복적으로 호출하여 세마포를 여러 번 입력할 WaitOne 수 있습니다. 이러한 항목의 일부 또는 전체를 해제하기 위해 스레드는 매개 변수가 없는 Release() 메서드 오버로드를 여러 번 호출하거나 해제할 항목 수를 지정하는 메서드 오버로드를 호출 Release(Int32) 할 수 있습니다.

클래스는 Semaphore 또는 Release호출에 스레드 ID를 WaitOne 적용하지 않습니다. 스레드가 세마포를 너무 많이 해제하지 않도록 하는 것은 프로그래머의 책임입니다. 예를 들어 세마포의 최대 개수가 2개인데 스레드 A와 스레드 B가 모두 세마포를 입력한다고 가정해 보겠습니다. 스레드 B의 프로그래밍 오류로 인해 두 번 호출 Release 되면 두 호출 모두 성공합니다. 그러면 세마포 개수가 다 차서 스레드 A가 Release를 호출하면 SemaphoreFullException이 throw됩니다.

세마포는 로컬 세마포와 명명된 시스템 세마포의 두 가지 유형입니다. 이름을 허용하는 생성자를 사용하여 개체를 만드는 Semaphore 경우 해당 이름의 운영 체제 세마포와 연결됩니다. 명명된 시스템 세마포는 운영 체제 전체에 표시되며 프로세스 활동을 동기화하는 데 사용할 수 있습니다. 동일한 명명된 시스템 세마포를 나타내는 여러 Semaphore 개체를 만들 수 있으며 메서드를 OpenExisting 사용하여 기존의 명명된 시스템 세마포를 열 수 있습니다.

로컬 세마포는 프로세스 내에만 존재합니다. 로컬 Semaphore 개체에 대한 참조가 있는 프로세스의 모든 스레드에서 사용할 수 있습니다. 각 Semaphore 개체는 별도의 로컬 세마포입니다.

주의

기본적으로 명명된 세마포는 해당 세마포를 만든 사용자로 제한되지 않습니다. 다른 사용자는 세마포를 여러 번 획득하고 해제하지 않음으로써 세마포를 방해하는 것을 포함하여 세마포를 열고 사용할 수 있습니다. 특정 사용자에 대한 액세스를 제한하려면 생성자 오버로드를 사용하거나 SemaphoreAcl 명명된 세마포를 SemaphoreSecurity 만들 때 를 전달할 수 있습니다. 신뢰할 수 없는 사용자가 코드를 실행 중일 수 있는 시스템에 대한 액세스 제한 없이 명명된 세마포를 사용하지 마세요.

생성자

Semaphore(Int32, Int32)

초기 항목 수와 최대 동시 항목 수를 지정하여 Semaphore 클래스의 새 인스턴스를 초기화합니다.

Semaphore(Int32, Int32, String)

초기 항목 수와 최대 동시 항목 수를 지정하고, 시스템 세마포 개체 이름을 선택적으로 지정하여 Semaphore 클래스의 새 인스턴스를 초기화합니다.

Semaphore(Int32, Int32, String, Boolean)

초기 항목 수 및 최대 동시 항목 수를 지정하고, 선택적으로 시스템 세마포 개체의 이름을 지정하고, 새 시스템 세마포가 만들어졌는지 여부를 나타내는 값을 받을 변수를 지정하여 Semaphore 클래스의 새 인스턴스를 초기화합니다.

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

초기 항목 수 및 최대 동시 항목 수를 지정하고, 선택적으로 시스템 세마포 개체의 이름을 지정하고, 새 시스템 세마포가 만들어졌는지 여부를 나타내는 값을 받을 변수를 지정하고, 시스템 세마포에 대한 액세스 제어 보안을 지정하여 Semaphore 클래스의 새 인스턴스를 초기화합니다.

필드

WaitTimeout

대기 핸들이 신호를 받기 전에 WaitAny(WaitHandle[], Int32, Boolean) 작업이 제한 시간을 초과했음을 나타냅니다. 이 필드는 상수입니다.

(다음에서 상속됨 WaitHandle)

속성

Handle
사용되지 않음.
사용되지 않음.

네이티브 운영 체제 핸들을 가져오거나 설정합니다.

(다음에서 상속됨 WaitHandle)
SafeWaitHandle

네이티브 운영 체제 핸들을 가져오거나 설정합니다.

(다음에서 상속됨 WaitHandle)

메서드

Close()

현재 WaitHandle에서 보유한 모든 리소스를 해제합니다.

(다음에서 상속됨 WaitHandle)
CreateObjRef(Type)

원격 개체와 통신하는 데 사용되는 프록시 생성에 필요한 모든 관련 정보가 들어 있는 개체를 만듭니다.

(다음에서 상속됨 MarshalByRefObject)
Dispose()

WaitHandle 클래스의 현재 인스턴스에서 사용하는 모든 리소스를 해제합니다.

(다음에서 상속됨 WaitHandle)
Dispose(Boolean)

파생 클래스에서 재정의된 경우 WaitHandle에서 사용하는 관리되지 않는 리소스를 해제하고 필요에 따라 관리되는 리소스를 해제합니다.

(다음에서 상속됨 WaitHandle)
Equals(Object)

지정된 개체가 현재 개체와 같은지 확인합니다.

(다음에서 상속됨 Object)
GetAccessControl()

명명된 시스템 세마포에 대한 액세스 제어 보안을 가져옵니다.

GetHashCode()

기본 해시 함수로 작동합니다.

(다음에서 상속됨 Object)
GetLifetimeService()
사용되지 않음.

이 인스턴스의 수명 정책을 제어하는 현재의 수명 서비스 개체를 검색합니다.

(다음에서 상속됨 MarshalByRefObject)
GetType()

현재 인스턴스의 Type을 가져옵니다.

(다음에서 상속됨 Object)
InitializeLifetimeService()
사용되지 않음.

이 인스턴스의 수명 정책을 제어하는 수명 서비스 개체를 가져옵니다.

(다음에서 상속됨 MarshalByRefObject)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.

(다음에서 상속됨 Object)
MemberwiseClone(Boolean)

현재 MarshalByRefObject 개체의 단순 복사본을 만듭니다.

(다음에서 상속됨 MarshalByRefObject)
OpenExisting(String)

이미 있는 경우 지정한 명명된 세마포를 엽니다.

OpenExisting(String, SemaphoreRights)

이미 있는 경우 지정한 명명된 세마포를 원하는 보안 액세스로 엽니다.

Release()

세마포를 종료하고 이전 카운트를 반환합니다.

Release(Int32)

지정된 횟수만큼 세마포를 종료하고 이전 카운트를 반환합니다.

SetAccessControl(SemaphoreSecurity)

명명된 시스템 세마포에 대한 액세스 제어 보안을 설정합니다.

ToString()

현재 개체를 나타내는 문자열을 반환합니다.

(다음에서 상속됨 Object)
TryOpenExisting(String, Semaphore)

지정한 명명된 세마포(이미 존재하는 경우)를 열고 작업이 성공했는지를 나타내는 값을 반환합니다.

TryOpenExisting(String, SemaphoreRights, Semaphore)

지정한 명명된 세마포(이미 존재하는 경우)를 원하는 보안 액세스로 열고 작업이 성공적으로 수행되었는지 여부를 나타내는 값을 반환합니다.

WaitOne()

현재 WaitHandle이(가) 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 WaitHandle)
WaitOne(Int32)

부호 있는 32비트 정수로 시간 간격(밀리초)을 지정하여 현재 WaitHandle이 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 WaitHandle)
WaitOne(Int32, Boolean)

부호 있는 32비트 정수로 시간 간격을 지정하고 대기 전에 동기화 도메인을 끝낼지 여부를 지정하여 현재 WaitHandle이 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 WaitHandle)
WaitOne(TimeSpan)

TimeSpan로 시간 간격을 지정하여 현재 인스턴스가 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 WaitHandle)
WaitOne(TimeSpan, Boolean)

TimeSpan로 시간 간격을 지정하고 대기 전에 동기화 도메인을 끝낼지 여부를 지정하여 현재 인스턴스가 신호를 받을 때까지 현재 스레드를 차단합니다.

(다음에서 상속됨 WaitHandle)

명시적 인터페이스 구현

IDisposable.Dispose()

이 API는 제품 인프라를 지원하며 코드에서 직접 사용되지 않습니다.

WaitHandle에서 사용하는 모든 리소스를 해제합니다.

(다음에서 상속됨 WaitHandle)

확장 메서드

GetAccessControl(Semaphore)

지정된 semaphore에 대한 보안 설명자를 반환합니다.

SetAccessControl(Semaphore, SemaphoreSecurity)

지정된 세마포에 대한 보안 설명자를 설정합니다.

GetSafeWaitHandle(WaitHandle)

네이티브 운영 체제 대기 핸들에 대한 안전한 핸들을 가져옵니다.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

네이티브 운영 체제 대기 핸들에 대한 안전한 핸들을 설정합니다.

적용 대상

스레드 보안

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

추가 정보