Поделиться через


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)

Исходный код:
Semaphore.cs
Исходный код:
Semaphore.cs
Исходный код:
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

Максимальное количество запросов семафора, которое может быть обеспеченно одновременно.

Исключения

Значение initialCount больше значения maximumCount.

Значение параметраmaximumCount меньше 1.

-или-

Значение параметраinitialCount меньше 0.

Примеры

В следующем примере создается семафор с максимальным числом 3 и начальным числом, равным нулю. В примере запускается пять потоков, которые блокируют ожидание семафора. Основной поток использует перегрузку Release(Int32) метода, чтобы увеличить число семафоров до максимального значения, позволяя трем потокам войти в семафор. Каждый поток использует Thread.Sleep метод для ожидания одной секунды для имитации работы, а затем вызывает перегрузку 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

Комментарии

Этот конструктор инициализирует неименованный семафор. Все потоки, использующие экземпляр такого семафора, должны иметь ссылки на экземпляр .

Если initialCount меньше maximumCount, результат будет таким же, как если бы текущий поток вызывал WaitOne (maximumCount минус initialCount) раз. Если вы не хотите резервировать записи для потока, создающего семафор, используйте то же число для maximumCount и initialCount.

См. также раздел

Применяется к

Semaphore(Int32, Int32, String)

Исходный код:
Semaphore.cs
Исходный код:
Semaphore.cs
Исходный код:
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 имя после исключения пространства имен должно быть допустимым именем файла.

Исключения

Значение initialCount больше значения maximumCount.

- или -

Только в .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 возникает исключение . В противном случае создается новый объект синхронизации.

Если именованный системный семафор не существует, он создается с начальным и максимальным числом, указанными initialCount в и maximumCount. Если именованный системный семафор уже существует и initialCountmaximumCount не используется, хотя недопустимые значения по-прежнему вызывают исключения. Если необходимо определить, был ли создан именованный системный семафор, используйте перегрузку Semaphore(Int32, Int32, String, Boolean) конструктора.

Важно!

При использовании этой перегрузки конструктора рекомендуется указать одинаковое число для initialCount и maximumCount. Если initialCount значение меньше , чем maximumCount, и создается именованный системный семафор, эффект будет таким же, как если бы текущий поток вызвал WaitOne (maximumCount минус initialCount) раз. Однако при этой перегрузке конструктора невозможно определить, был ли создан именованный системный семафор.

Если указать null или пустую строку для name, создается локальный семафор, как если бы вы вызвали перегрузку конструктора Semaphore(Int32, Int32) .

Поскольку именованные семафоры видны во всей операционной системе, их можно использовать для координации использования ресурсов в пределах процесса.

Если вы хотите узнать, существует ли именованный системный семафор, используйте OpenExisting метод . Метод OpenExisting пытается открыть существующий именованный семафор и создает исключение, если системный семафор не существует.

Внимание!

По умолчанию именованный семафор не ограничивается пользователем, который его создал. Другие пользователи могут открывать и использовать семафор, в том числе вмешиваться в семафор, получив семафор несколько раз и не отпуская его. Чтобы ограничить доступ для определенных пользователей, можно использовать перегрузку конструктора или SemaphoreAcl и передать при SemaphoreSecurity создании именованного семафора. Избегайте использования именованных семафоров без ограничений доступа в системах, в которых могут выполняться ненадежные пользователи, выполняющие код.

См. также раздел

Применяется к

Semaphore(Int32, Int32, String, Boolean)

Исходный код:
Semaphore.cs
Исходный код:
Semaphore.cs
Исходный код:
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

При возврате этот метод содержит значение true, если был создан локальный семафор (то есть если параметр name имеет значение null или содержит пустую строку) или был создан заданный именованный системный семафор; значение false, если указанный именованный семафор уже существовал. Этот параметр передается неинициализированным.

Исключения

Значение initialCount больше значения maximumCount.

- или -

Только в .NET Framework. name превышает значение MAX_PATH (260 символов).

Значение параметра maximumCount меньше 1.

-или-

Значение параметра initialCount меньше 0.

name недопустим. Это исключение может возникнуть по разным причинам, включая некоторые ограничения, установленные операционной системой (например, в отношении использования неизвестных префиксов или недопустимых символов). Обратите внимание, что в имени и общих префиксах Global\" и "Local\" учитывается регистр.

- или -

Произошла другая ошибка. Дополнительные сведения можно получить с помощью свойства HResult.

Только в Windows. Для name указано неизвестное пространство имен. Дополнительные сведения см. в статье Имена объектов.

Слишком длинное значение name. Ограничения длины могут зависеть от операционной системы или конфигурации.

Именованный семафор существует, доступ к нему безопасно регулируется, но пользователь не имеет прав FullControl.

Не удается создать объект синхронизации с указанным значением для параметра name. Возможно, другой объект синхронизации имеет такое же имя.

Примеры

В следующем примере кода показано поведение между процессами именованного семафора. В примере создается именованный семафор с максимальным числом 5 и начальным числом двух. То есть он резервирует три записи для потока, который вызывает конструктор. Если createNew имеет значение false, программа выполняет три вызова 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 возникает исключение . В противном случае создается новый объект синхронизации.

Этот конструктор инициализирует Semaphore объект , представляющий именованный системный семафор. Можно создать несколько Semaphore объектов, представляющих один и тот же именованный системный семафор.

Если именованный системный семафор не существует, он создается с начальным и максимальным числом, указанными initialCount в и maximumCount. Если именованный системный семафор уже существует и initialCountmaximumCount не используется, хотя недопустимые значения по-прежнему вызывают исключения. Используйте , createdNew чтобы определить, был ли создан системный семафор.

Если initialCount значение меньше maximumCount, а createdNew равно true, результат будет таким же, как если бы текущий поток вызывал WaitOne (maximumCount минус initialCount) раз.

Если указать null или пустую строку для name, создается локальный семафор, как если бы вы вызвали перегрузку конструктора 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

При возврате этот метод содержит значение true, если был создан локальный семафор (то есть если параметр name имеет значение null или содержит пустую строку) или был создан заданный именованный системный семафор; значение false, если указанный именованный семафор уже существовал. Этот параметр передается неинициализированным.

semaphoreSecurity
SemaphoreSecurity

Объект SemaphoreSecurity, представляющий безопасность управления доступом для применения к именованному системному семафору.

Исключения

Значение initialCount больше значения maximumCount.

- или -

Только в .NET Framework. name превышает значение MAX_PATH (260 символов).

Значение параметра maximumCount меньше 1.

-или-

Значение параметраinitialCount меньше 0.

Именованный семафор существует, доступ к нему безопасно регулируется, но пользователь не имеет прав FullControl.

name недопустим. Это исключение может возникнуть по разным причинам, включая некоторые ограничения, установленные операционной системой (например, в отношении использования неизвестных префиксов или недопустимых символов). Обратите внимание, что в имени и общих префиксах Global\" и "Local\" учитывается регистр.

- или -

Произошла другая ошибка. Дополнительные сведения можно получить с помощью свойства HResult.

Только в Windows. Для name указано неизвестное пространство имен. Дополнительные сведения см. в статье Имена объектов.

Слишком длинное значение name. Ограничения длины могут зависеть от операционной системы или конфигурации.

Не удается создать объект синхронизации с указанным значением для параметра name. Возможно, другой объект синхронизации имеет такое же имя.

Примеры

В следующем примере кода демонстрируется межпроцессное поведение именованного семафора с безопасностью управления доступом. В примере используется перегрузка OpenExisting(String) метода для проверки существования именованного семафора. Если семафор не существует, он создается с максимальным числом двух и с безопасностью управления доступом, которая запрещает текущему пользователю использовать семафор, но предоставляет право на чтение и изменение разрешений на семафор. При запуске скомпилированного примера из двух окон команд вторая копия вызовет исключение нарушения доступа при вызове OpenExisting(String) метода . Исключение перехвачено, и в примере используется перегрузка 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 возникает исключение . В противном случае создается новый объект синхронизации.

Этот конструктор инициализирует Semaphore объект , представляющий именованный системный семафор. Можно создать несколько Semaphore объектов, представляющих один и тот же именованный системный семафор.

Если именованный системный семафор не существует, он создается с указанной безопасностью управления доступом. Если именованный семафор существует, указанная безопасность управления доступом игнорируется.

Примечание

Вызывающий объект имеет полный контроль над вновь созданным Semaphore объектом, даже если semaphoreSecurity запрещает или не предоставляет некоторые права доступа текущему пользователю. Однако если текущий пользователь пытается получить другой Semaphore объект для представления того же именованного семафора с помощью конструктора OpenExisting или метода, применяется безопасность управления доступом Windows.

Если именованный системный семафор не существует, он создается с начальным и максимальным числом, указанными initialCount в и maximumCount. Если именованный системный семафор уже существует и initialCountmaximumCount не используется, хотя недопустимые значения по-прежнему вызывают исключения. Используйте параметр , createdNew чтобы определить, был ли системный семафор создан этим конструктором.

Если initialCount значение меньше maximumCount, а createdNew равно true, результат будет таким же, как если бы текущий поток вызывал WaitOne (maximumCount минус initialCount) раз.

Если указать null или пустую строку для name, создается локальный семафор, как если бы вы вызвали перегрузку конструктора Semaphore(Int32, Int32) . В этом случае createdNew всегда trueимеет значение .

Поскольку именованные семафоры видны во всей операционной системе, их можно использовать для координации использования ресурсов в пределах процесса.

Внимание!

По умолчанию именованный семафор не ограничивается пользователем, который его создал. Другие пользователи могут открывать и использовать семафор, в том числе вмешиваться в семафор, получив семафор несколько раз и не отпуская его. Чтобы ограничить доступ для определенных пользователей, можно передать SemaphoreSecurity при создании именованного семафора. Избегайте использования именованных семафоров без ограничений доступа в системах, в которых могут выполняться ненадежные пользователи, выполняющие код.

См. также раздел

Применяется к