Semaphore Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Ограничивает количество потоков, которые могут одновременно получить доступ к ресурсу или пулу ресурсов.
public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
- Наследование
- Наследование
- Атрибуты
Примеры
В следующем примере кода создается семафор с максимальным числом трех и начальным числом нуля. В примере начинаются пять потоков, которые блокируют ожидание семафора. Основной поток использует Release(Int32) перегрузку метода для увеличения числа семафора до максимального, что позволяет трем потокам входить в семафор. Каждый поток использует Thread.Sleep метод для ожидания одной секунды, для имитации работы, а затем вызывает Release() перегрузку метода, чтобы освободить семафор. Каждый раз при выпуске семафора отображается предыдущее число семафоров. Сообщения консоли отслеживают использование семафора. Имитированный рабочий интервал немного увеличивается для каждого потока, чтобы упростить чтение выходных данных.
using System;
using System.Threading;
public class Example
{
// A semaphore that simulates a limited resource pool.
//
private static Semaphore _pool;
// A padding interval to make the output more orderly.
private static int _padding;
public static void Main()
{
// Create a semaphore that can satisfy up to three
// concurrent requests. Use an initial count of zero,
// so that the entire semaphore count is initially
// owned by the main program thread.
//
_pool = new Semaphore(initialCount: 0, maximumCount: 3);
// Create and start five numbered threads.
//
for(int i = 1; i <= 5; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Worker));
// Start the thread, passing the number.
//
t.Start(i);
}
// Wait for half a second, to allow all the
// threads to start and to block on the semaphore.
//
Thread.Sleep(500);
// The main thread starts out holding the entire
// semaphore count. Calling Release(3) brings the
// semaphore count back to its maximum value, and
// allows the waiting threads to enter the semaphore,
// up to three at a time.
//
Console.WriteLine("Main thread calls Release(3).");
_pool.Release(releaseCount: 3);
Console.WriteLine("Main thread exits.");
}
private static void Worker(object num)
{
// Each worker thread begins by requesting the
// semaphore.
Console.WriteLine("Thread {0} begins " +
"and waits for the semaphore.", num);
_pool.WaitOne();
// A padding interval to make the output more orderly.
int padding = Interlocked.Add(ref _padding, 100);
Console.WriteLine("Thread {0} enters the semaphore.", num);
// The thread's "work" consists of sleeping for
// about a second. Each thread "works" a little
// longer, just to make the output more orderly.
//
Thread.Sleep(1000 + padding);
Console.WriteLine("Thread {0} releases the semaphore.", num);
Console.WriteLine("Thread {0} previous semaphore count: {1}",
num, _pool.Release());
}
}
Imports System.Threading
Public Class Example
' A semaphore that simulates a limited resource pool.
'
Private Shared _pool As Semaphore
' A padding interval to make the output more orderly.
Private Shared _padding As Integer
<MTAThread> _
Public Shared Sub Main()
' Create a semaphore that can satisfy up to three
' concurrent requests. Use an initial count of zero,
' so that the entire semaphore count is initially
' owned by the main program thread.
'
_pool = New Semaphore(0, 3)
' Create and start five numbered threads.
'
For i As Integer = 1 To 5
Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
'Dim t As New Thread(AddressOf Worker)
' Start the thread, passing the number.
'
t.Start(i)
Next i
' Wait for half a second, to allow all the
' threads to start and to block on the semaphore.
'
Thread.Sleep(500)
' The main thread starts out holding the entire
' semaphore count. Calling Release(3) brings the
' semaphore count back to its maximum value, and
' allows the waiting threads to enter the semaphore,
' up to three at a time.
'
Console.WriteLine("Main thread calls Release(3).")
_pool.Release(3)
Console.WriteLine("Main thread exits.")
End Sub
Private Shared Sub Worker(ByVal num As Object)
' Each worker thread begins by requesting the
' semaphore.
Console.WriteLine("Thread {0} begins " _
& "and waits for the semaphore.", num)
_pool.WaitOne()
' A padding interval to make the output more orderly.
Dim padding As Integer = Interlocked.Add(_padding, 100)
Console.WriteLine("Thread {0} enters the semaphore.", num)
' The thread's "work" consists of sleeping for
' about a second. Each thread "works" a little
' longer, just to make the output more orderly.
'
Thread.Sleep(1000 + padding)
Console.WriteLine("Thread {0} releases the semaphore.", num)
Console.WriteLine("Thread {0} previous semaphore count: {1}", _
num, _
_pool.Release())
End Sub
End Class
Комментарии
Semaphore Используйте класс для управления доступом к пулу ресурсов. Потоки вводят семафор путем вызова WaitOne метода, унаследованного от WaitHandle класса, и выпуска семафора путем вызова Release метода.
Количество семафоров уменьшается каждый раз, когда поток входит в семафор и увеличивается при выпуске семафора потока. Если число равно нулю, последующие запросы блокируются до тех пор, пока другие потоки не отпустит семафор. Когда все потоки выпустили семафор, счетчик находится в максимальном значении, указанном при создании семафора.
Нет гарантированного заказа, например FIFO или LIFO, в котором заблокированные потоки входят в семафор.
Поток может ввести семафор несколько раз, вызвав WaitOne метод многократно. Чтобы освободить некоторые или все эти записи, поток может вызывать перегрузку метода без Release() параметров несколько раз или вызвать Release(Int32) перегрузку метода, указывающую количество записей, которые необходимо освободить.
Класс Semaphore не применяет удостоверение потока для вызовов WaitOne или Release. Ответственность программиста заключается в том, чтобы потоки не выпускали семафор слишком много раз. Например, предположим, что семафор имеет максимальное значение два, и поток A и поток B входят в семафор. Если ошибка программирования в потоке B приводит к вызову Release дважды, оба вызова успешно выполняются. Счетчик семафора полон, и когда поток A в конечном итоге вызывает Release, SemaphoreFullException выбрасывается.
Семафоры имеют два типа: локальные семафоры и именованные системные семафоры. При создании Semaphore объекта с помощью конструктора, который принимает имя, он связан с семафором операционной системы этого имени. Именованные системные семафоры видны во всей операционной системе и могут использоваться для синхронизации действий процессов. Можно создать несколько Semaphore объектов, представляющих один и тот же именованный системный семафор, и использовать OpenExisting этот метод для открытия существующего именованного семафора системы.
Локальный семафор существует только в процессе. Его можно использовать любым потоком в процессе с ссылкой на локальный Semaphore объект. Каждый Semaphore объект является отдельным локальным семафором.
Предостережение
По умолчанию именованный семафор не ограничивается пользователем, создающим его. Другие пользователи могут открывать и использовать семафор, включая вмешательство в семафор путем получения семафора несколько раз и не выпуская его. Чтобы ограничить доступ к определенным пользователям, можно использовать перегрузку конструктора или SemaphoreAcl передать ее при SemaphoreSecurity создании именованного семафора. Избегайте использования именованных семафоров без ограничений доступа к системам, у которых могут быть ненадежные пользователи, выполняющие код.
Конструкторы
| Имя | Описание |
|---|---|
| Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей, при необходимости указывая имя объекта системного семафора, указывая переменную, которая получает значение, указывающее, был ли создан новый системный семафор и указывая управление доступом безопасности для системного семафора. |
| Semaphore(Int32, Int32, String, Boolean) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей, при необходимости указывая имя объекта системного семафора и указывая переменную, которая получает значение, указывающее, был ли создан новый системный семафор. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей, при необходимости указывая имя объекта системного семафора и параметры для задания доступа к области пользователя и области сеанса и указания переменной, которая получает значение, указывающее, был ли создан новый системный семафор. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей, а также при необходимости указывая имя объекта системного семафора и параметры для задания доступа к области пользователя и области сеанса. |
| Semaphore(Int32, Int32, String) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей, а также при необходимости указывая имя объекта системного семафора. |
| Semaphore(Int32, Int32) |
Инициализирует новый экземпляр Semaphore класса, указывая начальное число записей и максимальное число одновременных записей. |
Поля
| Имя | Описание |
|---|---|
| WaitTimeout |
Указывает, что операция истекла до того, WaitAny(WaitHandle[], Int32, Boolean) как любой из дескрипторов ожидания был сигналирован. Это поле является константой. (Унаследовано от WaitHandle) |
Свойства
| Имя | Описание |
|---|---|
| Handle |
Устаревшие..
Устаревшие..
Возвращает или задает дескриптор собственной операционной системы. (Унаследовано от WaitHandle) |
| SafeWaitHandle |
Возвращает или задает дескриптор собственной операционной системы. (Унаследовано от WaitHandle) |
Методы
| Имя | Описание |
|---|---|
| Close() |
Освобождает все ресурсы, удерживаемые текущим WaitHandle. (Унаследовано от WaitHandle) |
| CreateObjRef(Type) |
Создает объект, содержащий все соответствующие сведения, необходимые для создания прокси-сервера, используемого для взаимодействия с удаленным объектом. (Унаследовано от MarshalByRefObject) |
| Dispose() |
Освобождает все ресурсы, используемые текущим экземпляром класса WaitHandle. (Унаследовано от WaitHandle) |
| Dispose(Boolean) |
При переопределении в производном классе освобождает неуправляемые ресурсы, используемые и WaitHandleпри необходимости освобождает управляемые ресурсы. (Унаследовано от WaitHandle) |
| Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
| GetAccessControl() |
Возвращает безопасность управления доступом для именованного системного семафора. |
| GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
| GetLifetimeService() |
Устаревшие..
Извлекает текущий объект службы времени существования, который управляет политикой времени существования для этого экземпляра. (Унаследовано от MarshalByRefObject) |
| GetType() |
Возвращает Type текущего экземпляра. (Унаследовано от Object) |
| InitializeLifetimeService() |
Устаревшие..
Получает объект службы времени существования для управления политикой времени существования для этого экземпляра. (Унаследовано от MarshalByRefObject) |
| MemberwiseClone() |
Создает неглубокую копию текущей Object. (Унаследовано от Object) |
| MemberwiseClone(Boolean) |
Создает неглубокую копию текущего MarshalByRefObject объекта. (Унаследовано от MarshalByRefObject) |
| OpenExisting(String, NamedWaitHandleOptions) |
Открывает указанный именованный семафор, если он уже существует. Если параметры заданы только для текущего пользователя, элементы управления доступом объекта проверяются для вызывающего пользователя. |
| OpenExisting(String, SemaphoreRights) |
Открывает указанный именованный семафор, если он уже существует, с требуемым доступом к безопасности. |
| OpenExisting(String) |
Открывает указанный именованный семафор, если он уже существует. |
| Release() |
Завершает семафор и возвращает предыдущее число. |
| Release(Int32) |
Завершает семафор заданное количество раз и возвращает предыдущее число. |
| SetAccessControl(SemaphoreSecurity) |
Задает безопасность управления доступом для именованного системного семафора. |
| ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
| TryOpenExisting(String, NamedWaitHandleOptions, Semaphore) |
Открывает указанный именованный семафор, если он уже существует, и возвращает значение, указывающее, выполнена ли операция успешно. Если параметры заданы только для текущего пользователя, элементы управления доступом объекта проверяются для вызывающего пользователя. |
| TryOpenExisting(String, Semaphore) |
Открывает указанный именованный семафор, если он уже существует, и возвращает значение, указывающее, выполнена ли операция успешно. |
| TryOpenExisting(String, SemaphoreRights, Semaphore) |
Открывает указанный именованный семафор, если он уже существует, при требуемом доступе к безопасности и возвращает значение, указывающее, выполнена ли операция успешно. |
| WaitOne() |
Блокирует текущий поток, пока текущий WaitHandle не получит сигнал. (Унаследовано от WaitHandle) |
| WaitOne(Int32, Boolean) |
Блокирует текущий поток, пока текущий WaitHandle не получит сигнал, используя 32-разрядное целое число со знаком, чтобы указать интервал времени и указать, следует ли выйти из домена синхронизации перед ожиданием. (Унаследовано от WaitHandle) |
| WaitOne(Int32) |
Блокирует текущий поток, пока текущий WaitHandle не получит сигнал, используя 32-разрядное целое число со знаком, чтобы указать интервал времени в миллисекундах. (Унаследовано от WaitHandle) |
| WaitOne(TimeSpan, Boolean) |
Блокирует текущий поток, пока текущий экземпляр не получит сигнал, используя TimeSpan интервал времени и указав, следует ли выйти из домена синхронизации перед ожиданием. (Унаследовано от WaitHandle) |
| WaitOne(TimeSpan) |
Блокирует текущий поток, пока текущий экземпляр не получит сигнал, используя TimeSpan интервал времени. (Унаследовано от WaitHandle) |
Явные реализации интерфейса
| Имя | Описание |
|---|---|
| IDisposable.Dispose() |
Этот API поддерживает инфраструктуру продукта и не предназначен для использования непосредственно из программного кода. Освобождает все ресурсы, используемые параметром WaitHandle. (Унаследовано от WaitHandle) |
Методы расширения
| Имя | Описание |
|---|---|
| GetAccessControl(Semaphore) |
Возвращает дескрипторы безопасности для указанного |
| GetSafeWaitHandle(WaitHandle) |
Возвращает безопасный дескриптор для собственного дескриптора ожидания операционной системы. |
| SetAccessControl(Semaphore, SemaphoreSecurity) |
Задает дескрипторы безопасности для указанного семафора. |
| SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Задает безопасный дескриптор для собственного дескриптора ожидания операционной системы. |
Применяется к
Потокобезопасность
Этот тип является потокобезопасной.