Semaphore 생성자

정의

Semaphore 클래스의 새 인스턴스를 초기화합니다.

오버로드

Semaphore(Int32, Int32)

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

Semaphore(Int32, Int32, String)

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

Semaphore(Int32, Int32, String, Boolean)

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

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

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

Semaphore(Int32, Int32)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

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

public:
 Semaphore(int initialCount, int maximumCount);
public Semaphore (int initialCount, int maximumCount);
new System.Threading.Semaphore : int * int -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer)

매개 변수

initialCount
Int32

세마포에 동시에 부여할 수 있는 초기 요청 수입니다.

maximumCount
Int32

세마포에 동시에 부여할 수 있는 최대 요청 수입니다.

예외

initialCountmaximumCount보다 큰 경우

maximumCount 가 1보다 작습니다.

또는

initialCount 가 0보다 작습니다.

예제

다음 예제에서는 최대 3개와 초기 개수가 0인 세마포를 만듭니다. 이 예제에서는 세마포 대기를 차단하는 5개의 스레드를 시작합니다. 기본 스레드는 메서드 오버로드를 사용하여 Release(Int32) 세마포 수를 최대값으로 늘려 세 개의 스레드가 세마포에 들어갈 수 있도록 합니다. 각 스레드는 메서드를 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

설명

이 생성자는 명명되지 않은 세마포를 초기화합니다. 이러한 세마포의 instance 사용하는 모든 스레드에는 instance 대한 참조가 있어야 합니다.

가 보다 작으면 initialCount 현재 스레드가 (maximumCountinitialCount기 ) 시간을 호출 WaitOne 한 경우와 효과가 maximumCount동일합니다. 세마포를 만드는 스레드에 대한 항목을 예약하지 않으려면 및 initialCountmaximumCount 대해 동일한 숫자를 사용합니다.

추가 정보

적용 대상

Semaphore(Int32, Int32, String)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

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

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name);
public Semaphore (int initialCount, int maximumCount, string name);
public Semaphore (int initialCount, int maximumCount, string? name);
new System.Threading.Semaphore : int * int * string -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String)

매개 변수

initialCount
Int32

세마포에 동시에 부여할 수 있는 초기 요청 수입니다.

maximumCount
Int32

세마포에 동시에 부여할 수 있는 최대 요청 수입니다.

name
String

동기화 개체를 다른 프로세스와 공유할 예정이면 이름이고, 그렇지 않으면 null 또는 빈 문자열입니다. 이름은 대/소문자를 구분합니다. 백슬래시 문자(\)는 예약되어 있으며 네임스페이스를 지정하는 데만 사용할 수 있습니다. 네임스페이스에 대한 자세한 내용은 설명 섹션을 참조하세요. 운영 체제에 따라 이름에 대한 추가 제한이 있을 수 있습니다. 예를 들어 Unix 기반 운영 체제에서 네임스페이스를 제외한 후의 이름은 유효한 파일 이름이어야 합니다.

예외

initialCountmaximumCount보다 큰 경우

-또는-

.NET Framework에만 해당: name이 MAX_PATH(260자)보다 깁니다.

maximumCount가 1보다 작습니다.

또는

initialCount가 0보다 작은 경우.

name이 잘못되었습니다. 이유는 다양하며, 대표적인 이유는 운영 체제가 적용하는 일부 제한(예: 알 수 없는 접두사나 잘못된 문자)입니다. 이름 및 일반 접두사 "Global\" 및 "Local\"은 대/소문자를 구분합니다.

-또는-

다른 오류가 발생했습니다. HResult 속성에서 자세한 정보를 확인할 수 있습니다.

Windows에만 해당: name이 알 수 없는 네임스페이스를 지정했습니다. 자세한 내용은 개체 이름을 참조하세요.

name이 너무 깁니다. 길이 제한은 운영 체제나 구성에 따라 달라집니다.

명명된 세마포가 존재하고 이 세마포에 액세스 제어 보안이 있고 사용자에게 FullControl이 없는 경우

이름이 name인 동기화 개체를 만들 수 없습니다. 다른 형식의 동기화 개체에 동일한 이름이 사용되었을 수 있습니다.

예제

다음 코드 예제에서는 명명된 세마포의 교차 프로세스 동작을 보여 줍니다. 이 예제에서는 최대 개수가 5이고 초기 개수가 5인 명명된 세마포를 만듭니다. 프로그램은 메서드를 세 번 호출합니다 WaitOne . 따라서 두 명령 창에서 컴파일된 예제를 실행하면 두 번째 복사본이 에 대한 세 번째 호출 WaitOne에서 차단됩니다. 프로그램의 첫 번째 복사본에서 하나 이상의 항목을 해제하여 두 번째 항목을 차단 해제합니다.

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

public ref class Example
{
public:
   static void main()
   {
      // Create a Semaphore object that represents the named
      // system semaphore "SemaphoreExample3". The semaphore has a
      // maximum count of five. The initial count is also five.
      // There is no point in using a smaller initial count,
      // because the initial count is not used if this program
      // doesn't create the named system semaphore, and with
      // this method overload there is no way to tell. Thus, this
      // program assumes that it is competing with other
      // programs for the semaphore.
      //
      Semaphore^ sem = gcnew Semaphore( 5,5,L"SemaphoreExample3" );
      
      // Attempt to enter the semaphore three times. If another
      // copy of this program is already running, only the first
      // two requests can be satisfied. The third blocks. Note
      // that in a real application, timeouts should be used
      // on the WaitOne calls, to avoid deadlocks.
      //
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore once." );
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore twice." );
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore three times." );
      
      // The thread executing this program has entered the
      // semaphore three times. If a second copy of the program
      // is run, it will block until this program releases the
      // semaphore at least once.
      //
      Console::WriteLine( L"Enter the number of times to call Release." );
      int n;
      if ( Int32::TryParse( Console::ReadLine(),n ) )
      {
         sem->Release( n );
      }

      int remaining = 3 - n;
      if ( remaining > 0 )
      {
         Console::WriteLine( L"Press Enter to release the remaining "
         L"count ({0}) and exit the program.", remaining );
         Console::ReadLine();
         sem->Release( remaining );
      }
   }
};
using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample3". The semaphore has a
        // maximum count of five. The initial count is also five. 
        // There is no point in using a smaller initial count,
        // because the initial count is not used if this program
        // doesn't create the named system semaphore, and with 
        // this method overload there is no way to tell. Thus, this
        // program assumes that it is competing with other
        // programs for the semaphore.
        //
        Semaphore sem = new Semaphore(5, 5, "SemaphoreExample3");

        // Attempt to enter the semaphore three times. If another 
        // copy of this program is already running, only the first
        // two requests can be satisfied. The third blocks. Note 
        // that in a real application, timeouts should be used
        // on the WaitOne calls, to avoid deadlocks.
        //
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore once.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore twice.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore three times.");

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    }
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample3". The semaphore has a
        ' maximum count of five. The initial count is also five. 
        ' There is no point in using a smaller initial count,
        ' because the initial count is not used if this program
        ' doesn't create the named system semaphore, and with 
        ' this method overload there is no way to tell. Thus, this
        ' program assumes that it is competing with other
        ' programs for the semaphore.
        '
        Dim sem As New Semaphore(5, 5, "SemaphoreExample3")

        ' Attempt to enter the semaphore three times. If another 
        ' copy of this program is already running, only the first
        ' two requests can be satisfied. The third blocks. Note 
        ' that in a real application, timeouts should be used
        ' on the WaitOne calls, to avoid deadlocks.
        '
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore once.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore twice.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore three times.")

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

설명

이 생성자는 명명된 Semaphore 시스템 세마포를 나타내는 개체를 초기화합니다. 동일한 명명된 시스템 세마포를 나타내는 여러 Semaphore 개체를 만들 수 있습니다.

name 접두사를 추가 Global\ 하거나 Local\ 네임스페이스를 지정할 수 있습니다. 네임스페이 Global 스를 지정하면 동기화 개체를 시스템의 모든 프로세스와 공유할 수 있습니다. Local 네임스페이스를 지정하면 네임스페이스가 지정되지 않은 경우에도 기본값이 되며, 동기화 개체를 동일한 세션의 프로세스와 공유할 수 있습니다. Windows에서 세션은 로그인 세션이며 서비스는 일반적으로 다른 비대화형 세션에서 실행됩니다. Unix와 유사한 운영 체제에서 각 셸에는 자체 세션이 있습니다. 세션-로컬 동기화 개체는 모두 동일한 세션에서 실행되는 부모/자식 관계와 프로세스 간의 동기화에 적합할 수 있습니다. Windows의 동기화 개체 이름에 대한 자세한 내용은 개체 이름을 참조하세요.

name 제공되고 요청된 형식의 동기화 개체가 네임스페이스에 이미 있는 경우 기존 동기화 개체가 사용됩니다. 다른 형식의 동기화 개체가 네임스페이스에 이미 있는 경우 이 WaitHandleCannotBeOpenedException throw됩니다. 그렇지 않으면 새 동기화 개체가 만들어집니다.

명명된 시스템 세마포가 없는 경우 및 maximumCount에 지정된 initialCount 초기 개수 및 최대 개수로 만들어집니다. 명명된 시스템 세마포가 initialCount 이미 있고 maximumCount 사용되지 않는 경우 잘못된 값으로 인해 예외가 발생합니다. 명명된 시스템 세마포가 만들어졌는지 여부를 결정해야 하는 경우 대신 생성자 오버로드를 Semaphore(Int32, Int32, String, Boolean) 사용합니다.

중요

이 생성자 오버로드를 사용하는 경우 및 maximumCount에 대해 동일한 숫자를 initialCount 지정하는 것이 좋습니다. initialCount 가 보다 maximumCount작고 명명된 시스템 세마포가 만들어지면 현재 스레드가 (maximumCountinitialCount기 ) 시간을 호출 WaitOne 한 경우와 효과가 동일합니다. 그러나 이 생성자 오버로드를 사용하면 명명된 시스템 세마포가 만들어졌는지 여부를 확인할 수 없습니다.

에 대해 또는 빈 문자열을 name지정 null 하면 생성자 오버로드를 호출한 것처럼 로컬 세마포가 Semaphore(Int32, Int32) 만들어집니다.

명명된 세마포는 운영 체제 전체에 표시되므로 프로세스 경계를 넘어 리소스 사용을 조정하는 데 사용할 수 있습니다.

명명된 시스템 세마포가 있는지 확인하려면 메서드를 OpenExisting 사용합니다. 메서드는 OpenExisting 기존의 명명된 세마포를 열려고 시도하고 시스템 세마포가 없는 경우 예외를 throw합니다.

주의

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

추가 정보

적용 대상

Semaphore(Int32, Int32, String, Boolean)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

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

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew);
public Semaphore (int initialCount, int maximumCount, string? name, out bool createdNew);
new System.Threading.Semaphore : int * int * string * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean)

매개 변수

initialCount
Int32

동시에 충족될 수 있는 세마포의 초기 요청 수입니다.

maximumCount
Int32

동시에 충족될 수 있는 세마포의 최대 요청 수입니다.

name
String

동기화 개체를 다른 프로세스와 공유할 예정이면 이름이고, 그렇지 않으면 null 또는 빈 문자열입니다. 이름은 대/소문자를 구분합니다. 백슬래시 문자(\)는 예약되어 있으며 네임스페이스를 지정하는 데만 사용할 수 있습니다. 네임스페이스에 대한 자세한 내용은 설명 섹션을 참조하세요. 운영 체제에 따라 이름에 대한 추가 제한이 있을 수 있습니다. 예를 들어 Unix 기반 운영 체제에서 네임스페이스를 제외한 후의 이름은 유효한 파일 이름이어야 합니다.

createdNew
Boolean

이 메서드가 반환될 때 로컬 세마포가 만들어진 경우(즉, namenull이거나 빈 문자열인 경우) 또는 지정한 명명된 시스템 세마포가 만들어진 경우에는 true가 포함되고, 지정한 명명된 시스템 세마포가 이미 있는 경우에는 false가 포함됩니다. 이 매개 변수는 초기화되지 않은 상태로 전달됩니다.

예외

initialCountmaximumCount보다 큰 경우

-또는-

.NET Framework에만 해당: name이 MAX_PATH(260자)보다 깁니다.

maximumCount가 1보다 작습니다.

또는

initialCount가 0보다 작은 경우.

name이 잘못되었습니다. 이유는 다양하며, 대표적인 이유는 운영 체제가 적용하는 일부 제한(예: 알 수 없는 접두사나 잘못된 문자)입니다. 이름 및 일반 접두사 "Global\" 및 "Local\"은 대/소문자를 구분합니다.

-또는-

다른 오류가 발생했습니다. HResult 속성에서 자세한 정보를 확인할 수 있습니다.

Windows에만 해당: name이 알 수 없는 네임스페이스를 지정했습니다. 자세한 내용은 개체 이름을 참조하세요.

name이 너무 깁니다. 길이 제한은 운영 체제나 구성에 따라 달라집니다.

명명된 세마포가 존재하고 이 세마포에 액세스 제어 보안이 있고 사용자에게 FullControl이 없는 경우

이름이 name인 동기화 개체를 만들 수 없습니다. 다른 형식의 동기화 개체에 동일한 이름이 사용되었을 수 있습니다.

예제

다음 코드 예제에서는 명명된 세마포의 교차 프로세스 동작을 보여 줍니다. 이 예제에서는 최대 개수가 5개이고 초기 개수가 2인 명명된 세마포를 만듭니다. 즉, 생성자를 호출하는 스레드에 대해 세 개의 항목을 예약합니다. 가 이falsecreateNew 프로그램에서 메서드를 세 번 호출합니다WaitOne. 따라서 두 명령 창에서 컴파일된 예제를 실행하면 두 번째 복사본이 에 대한 세 번째 호출 WaitOne에서 차단됩니다. 프로그램의 첫 번째 복사본에서 하나 이상의 항목을 해제하여 두 번째 항목을 차단 해제합니다.

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

public ref class Example
{
public:
   static void main()
   {
      // The value of this variable is set by the semaphore
      // constructor. It is true if the named system semaphore was
      // created, and false if the named semaphore already existed.
      //
      bool semaphoreWasCreated;
      
      // Create a Semaphore object that represents the named
      // system semaphore "SemaphoreExample". The semaphore has a
      // maximum count of five, and an initial count of two. The
      // Boolean value that indicates creation of the underlying
      // system object is placed in semaphoreWasCreated.
      //
      Semaphore^ sem = gcnew Semaphore( 2,5,L"SemaphoreExample",
         semaphoreWasCreated );
      if ( semaphoreWasCreated )
      {
         // If the named system semaphore was created, its count is
         // set to the initial count requested in the constructor.
         // In effect, the current thread has entered the semaphore
         // three times.
         //
         Console::WriteLine( L"Entered the semaphore three times." );
      }
      else
      {
         // If the named system semaphore was not created,
         // attempt to enter it three times. If another copy of
         // this program is already running, only the first two
         // requests can be satisfied. The third blocks.
         //
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore once." );
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore twice." );
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore three times." );
      }
      
      // The thread executing this program has entered the
      // semaphore three times. If a second copy of the program
      // is run, it will block until this program releases the
      // semaphore at least once.
      //
      Console::WriteLine( L"Enter the number of times to call Release." );
      int n;
      if ( Int32::TryParse( Console::ReadLine(), n ) )
      {
         sem->Release( n );
      }

      int remaining = 3 - n;
      if ( remaining > 0 )
      {
         Console::WriteLine( L"Press Enter to release the remaining "
         L"count ({0}) and exit the program.", remaining );
         Console::ReadLine();
         sem->Release( remaining );
      }
   }
};
using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // The value of this variable is set by the semaphore
        // constructor. It is true if the named system semaphore was
        // created, and false if the named semaphore already existed.
        //
        bool semaphoreWasCreated;

        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample". The semaphore has a
        // maximum count of five, and an initial count of two. The
        // Boolean value that indicates creation of the underlying 
        // system object is placed in semaphoreWasCreated.
        //
        Semaphore sem = new Semaphore(2, 5, "SemaphoreExample", 
            out semaphoreWasCreated);

        if (semaphoreWasCreated)
        {
            // If the named system semaphore was created, its count is
            // set to the initial count requested in the constructor.
            // In effect, the current thread has entered the semaphore
            // three times.
            // 
            Console.WriteLine("Entered the semaphore three times.");
        }
        else
        {      
            // If the named system semaphore was not created,  
            // attempt to enter it three times. If another copy of
            // this program is already running, only the first two
            // requests can be satisfied. The third blocks.
            //
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore once.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore twice.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore three times.");
        }

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    } 
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' The value of this variable is set by the semaphore
        ' constructor. It is True if the named system semaphore was
        ' created, and False if the named semaphore already existed.
        '
        Dim semaphoreWasCreated As Boolean

        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample". The semaphore has a
        ' maximum count of five, and an initial count of two. The
        ' Boolean value that indicates creation of the underlying 
        ' system object is placed in semaphoreWasCreated.
        '
        Dim sem As New Semaphore(2, 5, "SemaphoreExample", _
            semaphoreWasCreated)

        If semaphoreWasCreated Then
            ' If the named system semaphore was created, its count is
            ' set to the initial count requested in the constructor.
            ' In effect, the current thread has entered the semaphore
            ' three times.
            ' 
            Console.WriteLine("Entered the semaphore three times.")
        Else
            ' If the named system semaphore was not created,  
            ' attempt to enter it three times. If another copy of
            ' this program is already running, only the first two
            ' requests can be satisfied. The third blocks.
            '
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore once.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore twice.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore three times.")
        End If

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

설명

name 접두사를 추가 Global\ 하거나 Local\ 네임스페이스를 지정할 수 있습니다. 네임스페이 Global 스를 지정하면 동기화 개체를 시스템의 모든 프로세스와 공유할 수 있습니다. Local 네임스페이스를 지정하면 네임스페이스가 지정되지 않은 경우에도 기본값이 되며, 동기화 개체를 동일한 세션의 프로세스와 공유할 수 있습니다. Windows에서 세션은 로그인 세션이며 서비스는 일반적으로 다른 비대화형 세션에서 실행됩니다. Unix와 유사한 운영 체제에서 각 셸에는 자체 세션이 있습니다. 세션-로컬 동기화 개체는 모두 동일한 세션에서 실행되는 부모/자식 관계와 프로세스 간의 동기화에 적합할 수 있습니다. Windows의 동기화 개체 이름에 대한 자세한 내용은 개체 이름을 참조하세요.

name 제공되고 요청된 형식의 동기화 개체가 네임스페이스에 이미 있는 경우 기존 동기화 개체가 사용됩니다. 다른 형식의 동기화 개체가 네임스페이스에 이미 있는 경우 이 WaitHandleCannotBeOpenedException throw됩니다. 그렇지 않으면 새 동기화 개체가 만들어집니다.

이 생성자는 명명된 Semaphore 시스템 세마포를 나타내는 개체를 초기화합니다. 동일한 명명된 시스템 세마포를 나타내는 여러 Semaphore 개체를 만들 수 있습니다.

명명된 시스템 세마포가 없는 경우 및 maximumCount에 지정된 initialCount 초기 개수 및 최대 개수로 만들어집니다. 명명된 시스템 세마포가 initialCount 이미 있고 maximumCount 사용되지 않는 경우 잘못된 값으로 인해 예외가 발생합니다. 를 사용하여 createdNew 시스템 세마포가 만들어졌는지 여부를 확인합니다.

가 보다 maximumCount작고 createdNewtrue인 경우 initialCount 효과는 현재 스레드가 (maximumCount 빼기 initialCount) 시간을 호출 WaitOne 한 경우와 동일합니다.

에 대해 또는 빈 문자열을 name지정 null 하면 생성자 오버로드를 호출한 것처럼 로컬 세마포가 Semaphore(Int32, Int32) 만들어집니다. 이 경우 는 createdNew 항상 true입니다.

명명된 세마포는 운영 체제 전체에 표시되므로 프로세스 경계를 넘어 리소스 사용을 조정하는 데 사용할 수 있습니다.

주의

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

추가 정보

적용 대상

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

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

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::SemaphoreSecurity ^ semaphoreSecurity);
public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity);
new System.Threading.Semaphore : int * int * string * bool * System.Security.AccessControl.SemaphoreSecurity -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean, semaphoreSecurity As SemaphoreSecurity)

매개 변수

initialCount
Int32

동시에 충족될 수 있는 세마포의 초기 요청 수입니다.

maximumCount
Int32

동시에 충족될 수 있는 세마포의 최대 요청 수입니다.

name
String

동기화 개체를 다른 프로세스와 공유할 예정이면 이름이고, 그렇지 않으면 null 또는 빈 문자열입니다. 이름은 대/소문자를 구분합니다. 백슬래시 문자(\)는 예약되어 있으며 네임스페이스를 지정하는 데만 사용할 수 있습니다. 네임스페이스에 대한 자세한 내용은 설명 섹션을 참조하세요. 운영 체제에 따라 이름에 대한 추가 제한이 있을 수 있습니다. 예를 들어 Unix 기반 운영 체제에서 네임스페이스를 제외한 후의 이름은 유효한 파일 이름이어야 합니다.

createdNew
Boolean

이 메서드가 반환될 때 로컬 세마포가 만들어진 경우(즉, namenull이거나 빈 문자열인 경우) 또는 지정한 명명된 시스템 세마포가 만들어진 경우에는 true가 포함되고, 지정한 명명된 시스템 세마포가 이미 있는 경우에는 false가 포함됩니다. 이 매개 변수는 초기화되지 않은 상태로 전달됩니다.

semaphoreSecurity
SemaphoreSecurity

명명된 시스템 세마포에 적용할 액세스 제어 보안을 나타내는 SemaphoreSecurity 개체입니다.

예외

initialCountmaximumCount보다 큰 경우

-또는-

.NET Framework에만 해당: name이 MAX_PATH(260자)보다 깁니다.

maximumCount가 1보다 작습니다.

또는

initialCount 가 0보다 작습니다.

명명된 세마포가 존재하고 이 세마포에 액세스 제어 보안이 있고 사용자에게 FullControl이 없는 경우

name이 잘못되었습니다. 이유는 다양하며, 대표적인 이유는 운영 체제가 적용하는 일부 제한(예: 알 수 없는 접두사나 잘못된 문자)입니다. 이름 및 일반 접두사 "Global\" 및 "Local\"은 대/소문자를 구분합니다.

-또는-

다른 오류가 발생했습니다. HResult 속성에서 자세한 정보를 확인할 수 있습니다.

Windows에만 해당: name이 알 수 없는 네임스페이스를 지정했습니다. 자세한 내용은 개체 이름을 참조하세요.

name이 너무 깁니다. 길이 제한은 운영 체제나 구성에 따라 달라집니다.

이름이 name인 동기화 개체를 만들 수 없습니다. 다른 형식의 동기화 개체에 동일한 이름이 사용되었을 수 있습니다.

예제

다음 코드 예제에서는 액세스 제어 보안이 있는 명명된 세마포의 교차 프로세스 동작을 보여 줍니다. 이 예제에서는 메서드 오버로드를 사용하여 OpenExisting(String) 명명된 세마포가 있는지 테스트합니다. 세마포가 없는 경우 세마포를 사용할 수 있는 권한을 현재 사용자에게 거부하지만 세마포에 대한 권한을 읽고 변경할 수 있는 권한을 부여하는 액세스 제어 보안과 함께 최대 2개의 수로 생성됩니다. 두 명령 창에서 컴파일된 예제를 실행하는 경우 두 번째 복사본은 메서드 호출에서 액세스 위반 예외를 OpenExisting(String) throw합니다. 예외가 catch되고, 이 예제에서는 메서드 오버로드를 사용하여 OpenExisting(String, SemaphoreRights) 사용 권한을 읽고 변경하는 데 필요한 권한으로 세마포를 엽니다.

사용 권한이 변경되면 입력 및 해제에 필요한 권한으로 세마포가 열립니다. 세 번째 명령 창에서 컴파일된 예제를 실행하면 새 권한을 사용하여 실행됩니다.

#using <System.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Security::AccessControl;
using namespace System::Security::Permissions;

public ref class Example
{
public:
   [SecurityPermissionAttribute(SecurityAction::Demand, Flags = SecurityPermissionFlag::UnmanagedCode)]
   static void main()
   {
      String^ semaphoreName = L"SemaphoreExample5";

      Semaphore^ sem = nullptr;
      bool doesNotExist = false;
      bool unauthorized = false;
      
      // Attempt to open the named semaphore.
      try
      {
         // Open the semaphore with (SemaphoreRights.Synchronize
         // | SemaphoreRights.Modify), to enter and release the
         // named semaphore.
         //
         sem = Semaphore::OpenExisting( semaphoreName );
      }
      catch ( WaitHandleCannotBeOpenedException^ ex ) 
      {
         Console::WriteLine( L"Semaphore does not exist." );
         doesNotExist = true;
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
         unauthorized = true;
      }

      // There are three cases: (1) The semaphore does not exist.
      // (2) The semaphore exists, but the current user doesn't
      // have access. (3) The semaphore exists and the user has
      // access.
      //
      if ( doesNotExist )
      {
         // The semaphore does not exist, so create it.
         //
         // The value of this variable is set by the semaphore
         // constructor. It is true if the named system semaphore was
         // created, and false if the named semaphore already existed.
         //
         bool semaphoreWasCreated;
         
         // Create an access control list (ACL) that denies the
         // current user the right to enter or release the
         // semaphore, but allows the right to read and change
         // security information for the semaphore.
         //
         String^ user = String::Concat( Environment::UserDomainName,
            L"\\", Environment::UserName );
         SemaphoreSecurity^ semSec = gcnew SemaphoreSecurity;

         SemaphoreAccessRule^ rule = gcnew SemaphoreAccessRule( user,
            static_cast<SemaphoreRights>(
               SemaphoreRights::Synchronize |
               SemaphoreRights::Modify ),
            AccessControlType::Deny );
         semSec->AddAccessRule( rule );

         rule = gcnew SemaphoreAccessRule( user,
            static_cast<SemaphoreRights>(
               SemaphoreRights::ReadPermissions |
               SemaphoreRights::ChangePermissions ),
            AccessControlType::Allow );
         semSec->AddAccessRule( rule );
         
         // Create a Semaphore object that represents the system
         // semaphore named by the constant 'semaphoreName', with
         // maximum count three, initial count three, and the
         // specified security access. The Boolean value that
         // indicates creation of the underlying system object is
         // placed in semaphoreWasCreated.
         //
         sem = gcnew Semaphore( 3,3,semaphoreName,semaphoreWasCreated,semSec );
         
         // If the named system semaphore was created, it can be
         // used by the current instance of this program, even
         // though the current user is denied access. The current
         // program enters the semaphore. Otherwise, exit the
         // program.
         //
         if ( semaphoreWasCreated )
         {
            Console::WriteLine( L"Created the semaphore." );
         }
         else
         {
            Console::WriteLine( L"Unable to create the semaphore." );
            return;
         }

      }
      else if ( unauthorized )
      {
         // Open the semaphore to read and change the access
         // control security. The access control security defined
         // above allows the current user to do this.
         //
         try
         {
            sem = Semaphore::OpenExisting( semaphoreName,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::ReadPermissions |
                  SemaphoreRights::ChangePermissions ));
            
            // Get the current ACL. This requires
            // SemaphoreRights.ReadPermissions.
            SemaphoreSecurity^ semSec = sem->GetAccessControl();

            String^ user = String::Concat( Environment::UserDomainName,
               L"\\", Environment::UserName );
            
            // First, the rule that denied the current user
            // the right to enter and release the semaphore must
            // be removed.
            SemaphoreAccessRule^ rule = gcnew SemaphoreAccessRule( user,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::Synchronize |
                  SemaphoreRights::Modify ),
               AccessControlType::Deny );
            semSec->RemoveAccessRule( rule );
            
            // Now grant the user the correct rights.
            //
            rule = gcnew SemaphoreAccessRule( user,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::Synchronize |
                  SemaphoreRights::Modify ),
               AccessControlType::Allow );
            semSec->AddAccessRule( rule );
            
            // Update the ACL. This requires
            // SemaphoreRights.ChangePermissions.
            sem->SetAccessControl( semSec );

            Console::WriteLine( L"Updated semaphore security." );
            
            // Open the semaphore with (SemaphoreRights.Synchronize
            // | SemaphoreRights.Modify), the rights required to
            // enter and release the semaphore.
            //
            sem = Semaphore::OpenExisting( semaphoreName );

         }
         catch ( UnauthorizedAccessException^ ex ) 
         {
            Console::WriteLine( L"Unable to change permissions: {0}", ex->Message );
            return;
         }
      }
      
      // Enter the semaphore, and hold it until the program
      // exits.
      //
      try
      {
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore." );
         Console::WriteLine( L"Press the Enter key to exit." );
         Console::ReadLine();
         sem->Release();
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
      }
   }
};
using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string semaphoreName = "SemaphoreExample5";

        Semaphore sem = null;
        bool doesNotExist = false;
        bool unauthorized = false;

        // Attempt to open the named semaphore.
        try
        {
            // Open the semaphore with (SemaphoreRights.Synchronize
            // | SemaphoreRights.Modify), to enter and release the
            // named semaphore.
            //
            sem = Semaphore.OpenExisting(semaphoreName);
        }
        catch(WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Semaphore does not exist.");
            doesNotExist = true;
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
            unauthorized = true;
        }

        // There are three cases: (1) The semaphore does not exist.
        // (2) The semaphore exists, but the current user doesn't 
        // have access. (3) The semaphore exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The semaphore does not exist, so create it.
            //
            // The value of this variable is set by the semaphore
            // constructor. It is true if the named system semaphore was
            // created, and false if the named semaphore already existed.
            //
            bool semaphoreWasCreated;

            // Create an access control list (ACL) that denies the
            // current user the right to enter or release the 
            // semaphore, but allows the right to read and change
            // security information for the semaphore.
            //
            string user = Environment.UserDomainName + "\\" 
                + Environment.UserName;
            SemaphoreSecurity semSec = new SemaphoreSecurity();

            SemaphoreAccessRule rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                AccessControlType.Deny);
            semSec.AddAccessRule(rule);

            rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.ReadPermissions | SemaphoreRights.ChangePermissions,
                AccessControlType.Allow);
            semSec.AddAccessRule(rule);

            // Create a Semaphore object that represents the system
            // semaphore named by the constant 'semaphoreName', with
            // maximum count three, initial count three, and the
            // specified security access. The Boolean value that 
            // indicates creation of the underlying system object is
            // placed in semaphoreWasCreated.
            //
            sem = new Semaphore(3, 3, semaphoreName, 
                out semaphoreWasCreated, semSec);

            // If the named system semaphore was created, it can be
            // used by the current instance of this program, even 
            // though the current user is denied access. The current
            // program enters the semaphore. Otherwise, exit the
            // program.
            // 
            if (semaphoreWasCreated)
            {
                Console.WriteLine("Created the semaphore.");
            }
            else
            {
                Console.WriteLine("Unable to create the semaphore.");
                return;
            }
        }
        else if (unauthorized)
        {
            // Open the semaphore to read and change the access
            // control security. The access control security defined
            // above allows the current user to do this.
            //
            try
            {
                sem = Semaphore.OpenExisting(
                    semaphoreName, 
                    SemaphoreRights.ReadPermissions 
                        | SemaphoreRights.ChangePermissions);

                // Get the current ACL. This requires 
                // SemaphoreRights.ReadPermissions.
                SemaphoreSecurity semSec = sem.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\" 
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the semaphore must
                // be removed.
                SemaphoreAccessRule rule = new SemaphoreAccessRule(
                    user, 
                    SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                    AccessControlType.Deny);
                semSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new SemaphoreAccessRule(user, 
                     SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                     AccessControlType.Allow);
                semSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec);

                Console.WriteLine("Updated semaphore security.");

                // Open the semaphore with (SemaphoreRights.Synchronize 
                // | SemaphoreRights.Modify), the rights required to
                // enter and release the semaphore.
                //
                sem = Semaphore.OpenExisting(semaphoreName);
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}", ex.Message);
                return;
            }
        }

        // Enter the semaphore, and hold it until the program
        // exits.
        //
        try
        {
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore.");
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            sem.Release();
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
        }
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const semaphoreName As String = "SemaphoreExample5"

        Dim sem As Semaphore = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' Attempt to open the named semaphore.
        Try
            ' Open the semaphore with (SemaphoreRights.Synchronize
            ' Or SemaphoreRights.Modify), to enter and release the
            ' named semaphore.
            '
            sem = Semaphore.OpenExisting(semaphoreName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Semaphore does not exist.")
            doesNotExist = True
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", ex.Message)
            unauthorized = True
        End Try

        ' There are three cases: (1) The semaphore does not exist.
        ' (2) The semaphore exists, but the current user doesn't 
        ' have access. (3) The semaphore exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The semaphore does not exist, so create it.
            '
            ' The value of this variable is set by the semaphore
            ' constructor. It is True if the named system semaphore was
            ' created, and False if the named semaphore already existed.
            '
            Dim semaphoreWasCreated As Boolean

            ' Create an access control list (ACL) that denies the
            ' current user the right to enter or release the 
            ' semaphore, but allows the right to read and change
            ' security information for the semaphore.
            '
            Dim user As String = Environment.UserDomainName _ 
                & "\" & Environment.UserName
            Dim semSec As New SemaphoreSecurity()

            Dim rule As New SemaphoreAccessRule(user, _
                SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                AccessControlType.Deny)
            semSec.AddAccessRule(rule)

            rule = New SemaphoreAccessRule(user, _
                SemaphoreRights.ReadPermissions Or _
                SemaphoreRights.ChangePermissions, _
                AccessControlType.Allow)
            semSec.AddAccessRule(rule)

            ' Create a Semaphore object that represents the system
            ' semaphore named by the constant 'semaphoreName', with
            ' maximum count three, initial count three, and the
            ' specified security access. The Boolean value that 
            ' indicates creation of the underlying system object is
            ' placed in semaphoreWasCreated.
            '
            sem = New Semaphore(3, 3, semaphoreName, _
                semaphoreWasCreated, semSec)

            ' If the named system semaphore was created, it can be
            ' used by the current instance of this program, even 
            ' though the current user is denied access. The current
            ' program enters the semaphore. Otherwise, exit the
            ' program.
            ' 
            If semaphoreWasCreated Then
                Console.WriteLine("Created the semaphore.")
            Else
                Console.WriteLine("Unable to create the semaphore.")
                Return
            End If

        ElseIf unauthorized Then

            ' Open the semaphore to read and change the access
            ' control security. The access control security defined
            ' above allows the current user to do this.
            '
            Try
                sem = Semaphore.OpenExisting(semaphoreName, _
                    SemaphoreRights.ReadPermissions Or _
                    SemaphoreRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' SemaphoreRights.ReadPermissions.
                Dim semSec As SemaphoreSecurity = sem.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the semaphore must
                ' be removed.
                Dim rule As New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Deny)
                semSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Allow)
                semSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec)

                Console.WriteLine("Updated semaphore security.")

                ' Open the semaphore with (SemaphoreRights.Synchronize 
                ' Or SemaphoreRights.Modify), the rights required to
                ' enter and release the semaphore.
                '
                sem = Semaphore.OpenExisting(semaphoreName)

            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unable to change permissions: {0}", _
                    ex.Message)
                Return
            End Try

        End If

        ' Enter the semaphore, and hold it until the program
        ' exits.
        '
        Try
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore.")
            Console.WriteLine("Press the Enter key to exit.")
            Console.ReadLine()
            sem.Release()
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", _
                ex.Message)
        End Try
    End Sub 
End Class

설명

이 생성자를 사용하여 만들 때 명명된 시스템 세마포에 액세스 제어 보안을 적용하여 다른 코드가 세마포를 제어하지 못하도록 합니다.

name 접두사를 추가 Global\ 하거나 Local\ 네임스페이스를 지정할 수 있습니다. 네임스페이 Global 스를 지정하면 동기화 개체를 시스템의 모든 프로세스와 공유할 수 있습니다. Local 네임스페이스를 지정하면 네임스페이스가 지정되지 않은 경우에도 기본값이 되며, 동기화 개체를 동일한 세션의 프로세스와 공유할 수 있습니다. Windows에서 세션은 로그인 세션이며 서비스는 일반적으로 다른 비대화형 세션에서 실행됩니다. Unix와 유사한 운영 체제에서 각 셸에는 자체 세션이 있습니다. 세션 로컬 동기화 개체는 모두 동일한 세션에서 실행되는 부모/자식 관계와 프로세스 간의 동기화에 적합할 수 있습니다. Windows의 동기화 개체 이름에 대한 자세한 내용은 개체 이름을 참조하세요.

name 제공되고 요청된 형식의 동기화 개체가 네임스페이스에 이미 있는 경우 기존 동기화 개체가 사용됩니다. 다른 형식의 동기화 개체가 네임스페이스에 WaitHandleCannotBeOpenedException 이미 있는 경우 이 throw됩니다. 그렇지 않으면 새 동기화 개체가 만들어집니다.

이 생성자는 명명된 Semaphore 시스템 세마포를 나타내는 개체를 초기화합니다. 동일한 명명된 시스템 세마포를 나타내는 여러 Semaphore 개체를 만들 수 있습니다.

명명된 시스템 세마포가 없는 경우 지정된 액세스 제어 보안을 사용하여 생성됩니다. 명명된 세마포가 있으면 지정된 액세스 제어 보안이 무시됩니다.

참고

호출자는 현재 사용자에게 일부 액세스 권한을 거부하거나 부여하지 않더라도 semaphoreSecurity 새로 만든 Semaphore 개체를 완전히 제어할 수 있습니다. 그러나 현재 사용자가 생성자 또는 OpenExisting 메서드를 사용하여 동일한 명명된 세마포를 나타내는 다른 Semaphore 개체를 얻으려고 하면 Windows 액세스 제어 보안이 적용됩니다.

명명된 시스템 세마포가 없으면 및 maximumCount에서 지정한 초기 개수와 최대 개수를 사용하여 생성됩니다initialCount. 명명된 시스템 세마포가 initialCount 이미 있고 maximumCount 사용되지 않는 경우 잘못된 값으로 인해 여전히 예외가 발생합니다. 매개 변수를 createdNew 사용하여 이 생성자가 시스템 세마포를 만들었는지 여부를 확인합니다.

가 보다 maximumCount작고 createdNewtrue인 경우 initialCount 효과는 현재 스레드가 (maximumCount 빼기 initialCount) 시간을 호출 WaitOne 한 경우와 동일합니다.

에 대해 또는 빈 문자열을 name지정 null 하면 생성자 오버로드를 호출한 것처럼 로컬 세마포가 Semaphore(Int32, Int32) 만들어집니다. 이 경우 는 createdNew 항상 true입니다.

명명된 세마포는 운영 체제 전체에 표시되므로 프로세스 경계를 넘어 리소스 사용을 조정하는 데 사용할 수 있습니다.

주의

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

추가 정보

적용 대상