Semaphore Classe

Definição

Limita o número de threads que podem acessar um recurso ou um pool de recursos simultaneamente.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
Herança
Atributos

Exemplos

O exemplo de código a seguir cria um semáforo com uma contagem máxima de três e uma contagem inicial de zero.The following code example creates a semaphore with a maximum count of three and an initial count of zero. O exemplo inicia cinco threads, que bloqueia a espera pelo semáforo.The example starts five threads, which block waiting for the semaphore. O thread principal usa a Release(Int32) sobrecarga do método para aumentar a contagem de semáforos para seu máximo, permitindo que três threads insiram o semáforo.The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. Cada thread usa o Thread.Sleep método para aguardar um segundo, para simular o trabalho e, em Release() seguida, chama a sobrecarga do método para liberar o semáforo.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. Cada vez que o semáforo é liberado, a contagem de semáforo anterior é exibida.Each time the semaphore is released, the previous semaphore count is displayed. Mensagens do console acompanham o uso de semáforo.Console messages track semaphore use. O intervalo de trabalho simulado aumenta um pouco para cada thread, para facilitar a leitura da saída.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

Comentários

Use a Semaphore classe para controlar o acesso a um pool de recursos.Use the Semaphore class to control access to a pool of resources. Os threads inserem o semáforo chamando WaitOne o método, que é herdado WaitHandle da classe e liberam o semáforo chamando o Release método.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.

A contagem em um semáforo é decrementada toda vez que um thread entra no semáforo e incrementado quando um thread libera o semáforo.The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. Quando a contagem for zero, as solicitações subsequentes serão bloqueadas até que outros threads liberem o semáforo.When the count is zero, subsequent requests block until other threads release the semaphore. Quando todos os threads lançaram o semáforo, a contagem está no valor máximo especificado quando o semáforo foi criado.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

Não há nenhuma ordem garantida, como PEPS ou UEPS, em que os threads bloqueados inserem o semáforo.There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

Um thread pode inserir o semáforo várias vezes, chamando o WaitOne método repetidamente.A thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. Para liberar algumas ou todas essas entradas, o thread pode chamar a sobrecarga do Release() método sem parâmetros várias vezes ou pode chamar a Release(Int32) sobrecarga do método que especifica o número de entradas a serem liberadas.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.

A Semaphore classe não impõe a identidade de thread em chamadas WaitOne para Releaseou.The Semaphore class does not enforce thread identity on calls to WaitOne or Release. É responsabilidade do programador garantir que os threads não liberem o semáforo muitas vezes.It is the programmer's responsibility to ensure that threads do not release the semaphore too many times. Por exemplo, suponha que um sinal tenha uma contagem máxima de dois, e que o thread A e o thread B insiram o sinal.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Se um erro de programação no thread B fizer com que Release ele chame duas vezes, ambas as chamadas serão realizadas com sucesso.If a programming error in thread B causes it to call Release twice, both calls succeed. A contagem no sinal está completa e quando o thread A eventualmente chama Release, uma SemaphoreFullException é lançada.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

Os semáforos são de dois tipos: semáforos locais e semáforos de sistema nomeados.Semaphores are of two types: local semaphores and named system semaphores. Se você criar um Semaphore objeto usando um construtor que aceite um nome, ele será associado a um semáforo de sistema operacional desse nome.If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. Os semáforos de sistema nomeados são visíveis em todo o sistema operacional e podem ser usados para sincronizar as atividades de processos.Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. Você pode criar vários Semaphore objetos que representam o mesmo semáforo nomeado do sistema e pode usar o OpenExisting método para abrir um semáforo do sistema nomeado existente.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.

Um semáforo local existe somente dentro de seu processo.A local semaphore exists only within your process. Ele pode ser usado por qualquer thread em seu processo que tenha referência ao objeto Semaphore local.It can be used by any thread in your process that has a reference to the local Semaphore object. Cada Semaphore objeto é um semáforo local separado.Each Semaphore object is a separate local semaphore.

Construtores

Semaphore(Int32, Int32)

Inicializa uma nova instância da classe Semaphore, especificando o número inicial de entradas e o número máximo de entradas simultâneas.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)

Inicializa uma nova instância da classe Semaphore, especificando o número inicial de entradas e o número máximo de entradas simultâneas e, opcionalmente, especificando o nome de um objeto de sinal de sistema.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)

Inicializa uma nova instância da classe Semaphore, especificando o número inicial de entradas e o número máximo de entradas simultâneas, opcionalmente especificando o nome de um objeto de semáforo de sistema e especificando uma variável que recebe um valor que indica se um novo semáforo do sistema foi criado.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)

Inicializa uma nova instância da classe Semaphore, especificando o número inicial de entradas e o número máximo de entradas simultâneas, opcionalmente especificando o nome de um objeto de semáforo de sistema, especificando uma variável que recebe um valor que indica se um novo semáforo do sistema foi criado e especificando o controle de acesso de segurança para o semáforo do sistema.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.

Campos

WaitTimeout

Indica que uma operação WaitAny(WaitHandle[], Int32, Boolean) atingiu o tempo limite antes que algum dos identificadores de espera fosse sinalizado.Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. Este campo é constante.This field is constant.

(Herdado de WaitHandle)

Propriedades

Handle

Obtém ou define o identificador de sistema operacional nativo.Gets or sets the native operating system handle.

(Herdado de WaitHandle)
SafeWaitHandle

Obtém ou define o identificador de sistema operacional nativo.Gets or sets the native operating system handle.

(Herdado de WaitHandle)

Métodos

Close()

Libera todos os recursos mantidos pelo WaitHandle atual.Releases all resources held by the current WaitHandle.

(Herdado de WaitHandle)
CreateObjRef(Type)

Cria um objeto que contém todas as informações relevantes necessárias para gerar um proxy usado para se comunicar com um objeto remoto.Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

(Herdado de MarshalByRefObject)
Dispose()

Libera todos os recursos usados pela instância atual da classe WaitHandle.Releases all resources used by the current instance of the WaitHandle class.

(Herdado de WaitHandle)
Dispose(Boolean)

Quando substituído em uma classe derivada, libera os recursos não gerenciados usados pelo WaitHandle e, opcionalmente, libera os recursos gerenciados.When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

(Herdado de WaitHandle)
Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.Determines whether the specified object is equal to the current object.

(Herdado de Object)
GetAccessControl()

Define a segurança de controle de acesso para um semáforo de sistema nomeado.Gets the access control security for a named system semaphore.

GetHashCode()

Serve como a função de hash padrão.Serves as the default hash function.

(Herdado de Object)
GetLifetimeService()

Recupera o objeto de serviço de tempo de vida atual que controla a política de ciclo de vida para esta instância.Retrieves the current lifetime service object that controls the lifetime policy for this instance.

(Herdado de MarshalByRefObject)
GetType()

Obtém o Type da instância atual.Gets the Type of the current instance.

(Herdado de Object)
InitializeLifetimeService()

Obtém um objeto de serviço de tempo de vida para controlar a política de tempo de vida para essa instância.Obtains a lifetime service object to control the lifetime policy for this instance.

(Herdado de MarshalByRefObject)
MemberwiseClone()

Cria uma cópia superficial do Object atual.Creates a shallow copy of the current Object.

(Herdado de Object)
MemberwiseClone(Boolean)

Cria uma cópia superficial do objeto MarshalByRefObject atual.Creates a shallow copy of the current MarshalByRefObject object.

(Herdado de MarshalByRefObject)
OpenExisting(String)

Abre o semáforo nomeado especificado, caso ele já exista.Opens the specified named semaphore, if it already exists.

OpenExisting(String, SemaphoreRights)

Abre o semáforo nomeado especificado, caso ele já exista, com o acesso de segurança desejado.Opens the specified named semaphore, if it already exists, with the desired security access.

Release()

Sai do sinal e retorna à contagem anterior.Exits the semaphore and returns the previous count.

Release(Int32)

Sai do sinal de um número de vezes especificado e retorna à contagem anterior.Exits the semaphore a specified number of times and returns the previous count.

SetAccessControl(SemaphoreSecurity)

Define a segurança de controle de acesso para um semáforo de sistema nomeado.Sets the access control security for a named system semaphore.

ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.Returns a string that represents the current object.

(Herdado de Object)
TryOpenExisting(String, Semaphore)

Abre o semáforo nomeado especificado, caso ele já exista e retorna um valor que indica se a operação foi bem-sucedida.Opens the specified named semaphore, if it already exists, and returns a value that indicates whether the operation succeeded.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Se o semáforo nomeado especificado já existe, abre-o com o acesso de segurança desejado e retorna um valor que indica se a operação foi bem-sucedida.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()

Bloqueia o thread atual até que o WaitHandle atual receba um sinal.Blocks the current thread until the current WaitHandle receives a signal.

(Herdado de WaitHandle)
WaitOne(Int32)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo em milissegundos.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

(Herdado de WaitHandle)
WaitOne(Int32, Boolean)

Bloqueia o thread atual até que o WaitHandle atual receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.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.

(Herdado de WaitHandle)
WaitOne(TimeSpan)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

(Herdado de WaitHandle)
WaitOne(TimeSpan, Boolean)

Bloqueia o thread atual até que a instância atual receba um sinal, usando um TimeSpan para especificar o intervalo de tempo e especificar se sairá do domínio de sincronização antes da espera.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.

(Herdado de WaitHandle)

Implantações explícitas de interface

IDisposable.Dispose()

Libera todos os recursos usados pelo WaitHandle.Releases all resources used by the WaitHandle.

(Herdado de WaitHandle)

Métodos de Extensão

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

Obtém o identificador seguro para um identificador de espera nativo do sistema operacional.Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Define um identificador seguro para um identificador de espera do sistema operacional nativo.Sets a safe handle for a native operating system wait handle.

Aplica-se a

Acesso thread-safe

Este tipo é thread-safe.This type is thread safe.

Veja também