Semaphore Класс

Определение

Ограничивает число потоков, которые могут одновременно обращаться к ресурсу или пулу ресурсов.Limits the number of threads that can access a resource or pool of resources concurrently.

public ref class Semaphore sealed : System::Threading::WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
Наследование
Атрибуты

Примеры

В следующем примере кода создается семафор с максимальным числом трех и начальным счетчиком, равным нулю.The following code example creates a semaphore with a maximum count of three and an initial count of zero. В примере запускается пять потоков, которые блокируют ожидание семафора.The example starts five threads, which block waiting for the semaphore. Основной поток использует Release(Int32) перегрузку метода для увеличения числа семафоров до максимального значения, позволяя трем потокам входить в семафор.The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. Каждый поток использует Thread.Sleep метод для ожидания одной секунды, для имитации работы, а затем Release() вызывает перегрузку метода для освобождения семафора.Each thread uses the Thread.Sleep method to wait for one second, to simulate work, and then calls the Release() method overload to release the semaphore. При каждом освобождении семафора отображается предыдущее число семафоров.Each time the semaphore is released, the previous semaphore count is displayed. Сообщения консоли записывают использование семафора.Console messages track semaphore use. Рабочий интервал смоделированной работы немного увеличивается для каждого потока, чтобы упростить чтение выходных данных.The simulated work interval is increased slightly for each thread, to make the output easier to read.

#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(0, 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(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 Используйте класс для управления доступом к пулу ресурсов.Use the Semaphore class to control access to a pool of resources. Потоки вводят семафор, вызывая WaitOne метод, который наследуется WaitHandle от класса, и освобождает семафор, вызывая Release метод.Threads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, and release the semaphore by calling the Release method.

Счетчик для семафора уменьшается каждый раз, когда поток входит в семафор, и увеличивается, когда поток освобождает семафор.The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. Если значение счетчика равно нулю, последующие запросы блокируются до освобождения семафора другими потоками.When the count is zero, subsequent requests block until other threads release the semaphore. Когда семафор освобожден всеми потоками, счетчик будет иметь максимальное значение, указанное при создании семафора.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

Нет гарантированного порядка, например FIFO или ЛИФО, в котором заблокированные потоки вводят семафор.There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

Поток может вводить семафор несколько раз, вызывая WaitOne метод многократно.A thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. Чтобы освободить некоторые или все эти записи, поток может вызвать перегрузку Release() метода без параметров несколько раз или Release(Int32) вызвать перегрузку метода, указывающую число освобожденных записей.To release some or all of these entries, the thread can call the parameterless Release() method overload multiple times, or it can call the Release(Int32) method overload that specifies the number of entries to be released.

Класс не применяет удостоверение потока при WaitOne вызовах Releaseили. SemaphoreThe Semaphore class does not enforce thread identity on calls to WaitOne or Release. Ответственность за то, чтобы потоки не освободили семафор слишком много раз, лежит на программисте.It is the programmer's responsibility to ensure that threads do not release the semaphore too many times. Например предположим, что семафор имеет максимальное значение счетчика равное двум, а два потока A и B входят в семафор.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Если ошибка программирования в потоке б приводит к вызову Release метода дважды, оба вызова будут выполнены.If a programming error in thread B causes it to call Release twice, both calls succeed. Счетчик на семафоре переполнен, и если поток A вызывает Release, SemaphoreFullException создается исключение.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

Семафоры имеют два типа: локальные семафоры и именованные системные семафоры.Semaphores are of two types: local semaphores and named system semaphores. При создании Semaphore объекта с помощью конструктора, который принимает имя, он связывается с семафором операционной системы этого имени.If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. Именованные системные семафоры видимы во всей операционной системе и могут использоваться для синхронизации действий процессов.Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. Можно создать несколько Semaphore объектов, представляющих один и тот же именованный системный семафор, и можно OpenExisting использовать метод, чтобы открыть существующий именованный системный семафор.You can create multiple Semaphore objects that represent the same named system semaphore, and you can use the OpenExisting method to open an existing named system semaphore.

Локальный семафор существует только в пределах процесса.A local semaphore exists only within your process. Его может использовать любой поток в вашем процессе, имеющий ссылку на локальный объект Semaphore.It can be used by any thread in your process that has a reference to the local Semaphore object. Каждый Semaphore объект является отдельным локальным семафором.Each Semaphore object is a separate local semaphore.

Конструкторы

Semaphore(Int32, Int32)

Инициализирует новый экземпляр класса Semaphore, задающий начальное количество входов и максимальное количество одновременных входов.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries.

Semaphore(Int32, Int32, String)

Инициализирует новый экземпляр класса Semaphore, задающий начальное количество входов и максимальное количество одновременных входов, а также при необходимости имя объекта системного семафора.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, and optionally specifying the name of a system semaphore object.

Semaphore(Int32, Int32, String, Boolean)

Инициализирует новый экземпляр класса Semaphore, задающий начальное количество входов и максимальное количество одновременных входов, а также при необходимости задающий имя объекта системного семафора и переменную, получающую значение, которое указывает, был ли создан новый системный семафор.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, and specifying a variable that receives a value indicating whether a new system semaphore was created.

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

Инициализирует новый экземпляр класса Semaphore, задающий начальное количество входов и максимальное количество одновременных входов, а также при необходимости задает имя объекта системного семафора, переменную, которая получает значение, указывающее, был ли создан новый системный семафор, и управление безопасным доступом для системного семафора.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, specifying a variable that receives a value indicating whether a new system semaphore was created, and specifying security access control for the system semaphore.

Поля

WaitTimeout

Указывает, что время ожидания операции WaitAny(WaitHandle[], Int32, Boolean) истекло до получения сигнала каким-либо из дескрипторов ожидания.Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. Это поле является константой.This field is constant.

(Унаследовано от WaitHandle)

Свойства

Handle

Возвращает или задает собственный дескриптор операционной системы.Gets or sets the native operating system handle.

(Унаследовано от WaitHandle)
SafeWaitHandle

Возвращает или задает собственный дескриптор операционной системы.Gets or sets the native operating system handle.

(Унаследовано от WaitHandle)

Методы

Close()

Освобождает все ресурсы, удерживаемые текущим объектом WaitHandle.Releases all resources held by the current WaitHandle.

(Унаследовано от WaitHandle)
CreateObjRef(Type)

Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

(Унаследовано от MarshalByRefObject)
Dispose()

Освобождает все ресурсы, используемые текущим экземпляром класса WaitHandle.Releases all resources used by the current instance of the WaitHandle class.

(Унаследовано от WaitHandle)
Dispose(Boolean)

При переопределении в производном классе освобождает неуправляемые ресурсы, используемые объектом WaitHandle, и при необходимости освобождает управляемые ресурсы.When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

(Унаследовано от WaitHandle)
Equals(Object)

Определяет, равен ли заданный объект текущему объекту.Determines whether the specified object is equal to the current object.

(Унаследовано от Object)
GetAccessControl()

Возвращает настройки управления доступом для именованного системного семафора.Gets the access control security for a named system semaphore.

GetHashCode()

Служит хэш-функцией по умолчанию.Serves as the default hash function.

(Унаследовано от Object)
GetLifetimeService()

Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.Retrieves the current lifetime service object that controls the lifetime policy for this instance.

(Унаследовано от MarshalByRefObject)
GetType()

Возвращает объект Type для текущего экземпляра.Gets the Type of the current instance.

(Унаследовано от Object)
InitializeLifetimeService()

Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.Obtains a lifetime service object to control the lifetime policy for this instance.

(Унаследовано от MarshalByRefObject)
MemberwiseClone()

Создает неполную копию текущего объекта Object.Creates a shallow copy of the current Object.

(Унаследовано от Object)
MemberwiseClone(Boolean)

Создает неполную копию текущего объекта MarshalByRefObject.Creates a shallow copy of the current MarshalByRefObject object.

(Унаследовано от MarshalByRefObject)
OpenExisting(String)

Открывает указанный именованный семафор, если он уже существует.Opens the specified named semaphore, if it already exists.

OpenExisting(String, SemaphoreRights)

Открывает указанный именованный семафор, если он уже существует, с требуемыми правами доступа.Opens the specified named semaphore, if it already exists, with the desired security access.

Release()

Выходит из семафора и возвращает последнее значение счетчика.Exits the semaphore and returns the previous count.

Release(Int32)

Выходит из семафора указанное число раз и возвращает последнее значение счетчика.Exits the semaphore a specified number of times and returns the previous count.

SetAccessControl(SemaphoreSecurity)

Задает настройки управления доступом для именованного системного семафора.Sets the access control security for a named system semaphore.

ToString()

Возвращает строку, представляющую текущий объект.Returns a string that represents the current object.

(Унаследовано от Object)
TryOpenExisting(String, Semaphore)

Открывает указанный именованный семафор, если он уже существует, и возвращает значение, указывающее, успешно ли выполнена операция.Opens the specified named semaphore, if it already exists, and returns a value that indicates whether the operation succeeded.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Открывает заданный именованный семафор, если он уже существует, с требуемыми правами доступа, и возвращает значение, указывающее, успешно ли выполнена операция.Opens the specified named semaphore, if it already exists, with the desired security access, and returns a value that indicates whether the operation succeeded.

WaitOne()

Блокирует текущий поток до получения сигнала объектом WaitHandle.Blocks the current thread until the current WaitHandle receives a signal.

(Унаследовано от WaitHandle)
WaitOne(Int32)

Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

(Унаследовано от WaitHandle)
WaitOne(Int32, Boolean)

Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(Унаследовано от WaitHandle)
WaitOne(TimeSpan)

Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для указания интервала времени.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

(Унаследовано от WaitHandle)
WaitOne(TimeSpan, Boolean)

Блокирует текущий поток до получения сигнала текущим экземпляром, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(Унаследовано от WaitHandle)

Явные реализации интерфейса

IDisposable.Dispose()

Освобождает все ресурсы, занятые модулем WaitHandle.Releases all resources used by the WaitHandle.

(Унаследовано от WaitHandle)

Методы расширения

GetAccessControl(Semaphore)
SetAccessControl(Semaphore, SemaphoreSecurity)
GetSafeWaitHandle(WaitHandle)

Возвращает безопасный дескриптор для собственного дескриптора ожидания операционной системы.Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Задает безопасный дескриптор для собственного дескриптора ожидания операционной системы.Sets a safe handle for a native operating system wait handle.

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

Потокобезопасность

Данный тип потокобезопасен.This type is thread safe.

Дополнительно