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
. Если именованный системный семафор уже существует и initialCount
maximumCount
не используется, хотя недопустимые значения по-прежнему вызывают исключения. Если необходимо определить, был ли создан именованный системный семафор, используйте перегрузку 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
. Если именованный системный семафор уже существует и initialCount
maximumCount
не используется, хотя недопустимые значения по-прежнему вызывают исключения. Используйте , 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
. Если именованный системный семафор уже существует и initialCount
maximumCount
не используется, хотя недопустимые значения по-прежнему вызывают исключения. Используйте параметр , createdNew
чтобы определить, был ли системный семафор создан этим конструктором.
Если initialCount
значение меньше maximumCount
, а createdNew
равно true
, результат будет таким же, как если бы текущий поток вызывал WaitOne (maximumCount
минус initialCount
) раз.
Если указать null
или пустую строку для name
, создается локальный семафор, как если бы вы вызвали перегрузку конструктора Semaphore(Int32, Int32) . В этом случае createdNew
всегда true
имеет значение .
Поскольку именованные семафоры видны во всей операционной системе, их можно использовать для координации использования ресурсов в пределах процесса.
Внимание!
По умолчанию именованный семафор не ограничивается пользователем, который его создал. Другие пользователи могут открывать и использовать семафор, в том числе вмешиваться в семафор, получив семафор несколько раз и не отпуская его. Чтобы ограничить доступ для определенных пользователей, можно передать SemaphoreSecurity при создании именованного семафора. Избегайте использования именованных семафоров без ограничений доступа в системах, в которых могут выполняться ненадежные пользователи, выполняющие код.