Semaphore Classe
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Limita o número de threads que podem aceder simultaneamente a um recurso ou conjunto de recursos.
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
- Herança
- Herança
- Atributos
Exemplos
O exemplo de código seguinte cria um semáforo com contagem máxima de três e contagem inicial de zero. O exemplo inicia cinco threads, que bloqueiam a espera do semáforo. A thread principal utiliza o Release(Int32) método overload para aumentar a contagem de semáforos ao máximo, permitindo que três threads entrem no semáforo. Cada thread usa o Thread.Sleep método para esperar um segundo para simular o trabalho, e depois chama o Release() método de sobrecarga para libertar o semáforo. Cada vez que o semáforo é libertado, é apresentada a contagem anterior de semáforos. As mensagens de consola acompanham o uso de semáforos. O intervalo de trabalho simulado é ligeiramente aumentado para cada thread, para facilitar a leitura da saída.
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
Observações
Usa a Semaphore classe para controlar o acesso a um conjunto de recursos. Os threads entram no semáforo chamando o WaitOne método, que é herdado da WaitHandle classe, e libertam o semáforo ao chamar o Release método.
A contagem num semáforo é decrementada cada vez que um fio entra no semáforo, e incrementada quando um fio liberta o semáforo. Quando a contagem é zero, os pedidos subsequentes bloqueiam até que outros threads libertem o semáforo. Quando todas as threads libertam o semáforo, a contagem está no valor máximo especificado quando o semáforo foi criado.
Não existe uma ordem garantida, como FIFO ou LIFO, em que threads bloqueados entrem no semáforo.
Um thread pode entrar no semáforo várias vezes, chamando o WaitOne método repetidamente. Para libertar algumas ou todas estas entradas, o thread pode chamar o método sem parâmetros Release() overload várias vezes, ou pode chamar o Release(Int32) método overload que especifica o número de entradas a libertar.
A Semaphore classe não impõe identidade de thread em chamadas para WaitOne ou Release. É responsabilidade do programador garantir que os threads não libertam o semáforo demasiadas vezes. Por exemplo, suponha que um semáforo tenha uma contagem máxima de dois, e que o fio A e o fio B entrem no semáforo. Se um erro de programação no thread B fizer com que ele chame Release duas vezes, ambas as chamadas serão bem-sucedidas. A contagem do semáforo está cheia, e quando o fio A eventualmente chama Release, um SemaphoreFullException é lançado.
Os semáforos são de dois tipos: semáforos locais e semáforos de sistemas nomeados. Se criares um Semaphore objeto usando um construtor que aceita um nome, ele está associado a um semáforo do sistema operativo com esse nome. Semáforos de sistemas nomeados são visíveis por todo o sistema operativo e podem ser usados para sincronizar as atividades dos processos. Podes criar múltiplos Semaphore objetos que representam o mesmo semáforo de sistema nomeado, e podes usar o OpenExisting método para abrir um semáforo de sistema já nomeado.
Um semáforo local existe apenas no seu processo. Ele pode ser usado por qualquer thread em seu processo que tenha uma referência ao objeto local Semaphore . Cada Semaphore objeto é um semáforo local separado.
Atenção
Por defeito, um semáforo nomeado não está restrito ao utilizador que o criou. Outros utilizadores podem conseguir abrir e usar o semáforo, incluindo interferir com ele ao adquiri-lo várias vezes sem o libertar. Para restringir o acesso a utilizadores específicos, podes usar um constructor overload ou SemaphoreAcl e passar um SemaphoreSecurity ao criar o semáforo nomeado. Evite usar semáforos nomeados sem restrições de acesso em sistemas que possam ter utilizadores não confiáveis a executar código.
Construtores
| Name | Description |
|---|---|
| Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity) |
Inicializa uma nova instância da Semaphore classe, especificando o número inicial de entradas e o número máximo de entradas concorrentes, especificando opcionalmente o nome de um objeto semáforo do sistema, especificando uma variável que recebe um valor indicando se foi criado um novo semáforo do sistema, e especificando controlo de acesso de segurança para o semáforo do sistema. |
| Semaphore(Int32, Int32, String, Boolean) |
Inicializa uma nova instância da Semaphore classe, especificando o número inicial de entradas e o número máximo de entradas concorrentes, opcionalmente especificando o nome de um objeto semáforo do sistema, e especificando uma variável que recebe um valor que indica se foi criado um novo semáforo do sistema. |
| Semaphore(Int32, Int32, String) |
Inicializa uma nova instância da Semaphore classe, especificando o número inicial de entradas e o número máximo de entradas concorrentes, e opcionalmente especificando o nome de um objeto semáforo do sistema. |
| Semaphore(Int32, Int32) |
Inicializa uma nova instância da Semaphore classe, especificando o número inicial de entradas e o número máximo de entradas concorrentes. |
Campos
| Name | Description |
|---|---|
| WaitTimeout |
Indica que uma WaitAny(WaitHandle[], Int32, Boolean) operação terminou antes de qualquer uma das alças de espera ser sinalizada. Este campo é constante. (Herdado de WaitHandle) |
Propriedades
| Name | Description |
|---|---|
| Handle |
Obsoleto.
Obtém ou define o handle nativo do sistema operativo. (Herdado de WaitHandle) |
| SafeWaitHandle |
Obtém ou define o handle nativo do sistema operativo. (Herdado de WaitHandle) |
Métodos
| Name | Description |
|---|---|
| Close() |
Liberta todos os recursos detidos pelo atual WaitHandle. (Herdado de WaitHandle) |
| CreateObjRef(Type) |
Cria um objeto que contém toda a informação relevante necessária para gerar um proxy usado para comunicar com um objeto remoto. (Herdado de MarshalByRefObject) |
| Dispose() |
Liberta todos os recursos usados pela instância atual da WaitHandle classe. (Herdado de WaitHandle) |
| Dispose(Boolean) |
Quando sobreposto numa classe derivada, liberta os recursos não geridos usados pelo WaitHandle, e opcionalmente liberta os recursos geridos. (Herdado de WaitHandle) |
| Equals(Object) |
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object) |
| GetAccessControl() |
Obtém a segurança de controlo de acesso para um semáforo de sistema nomeado. |
| GetHashCode() |
Serve como função de hash predefinida. (Herdado de Object) |
| GetLifetimeService() |
Recupera o objeto de serviço de tempo de vida atual que controla a política de vida útil neste caso. (Herdado de MarshalByRefObject) |
| GetType() |
Obtém o Type da instância atual. (Herdado de Object) |
| InitializeLifetimeService() |
Obtém-se um objeto de serviço vitalício para controlar a apólice vitalícia neste caso. (Herdado de MarshalByRefObject) |
| MemberwiseClone() |
Cria uma cópia superficial do atual Object. (Herdado de Object) |
| MemberwiseClone(Boolean) |
Cria uma cópia superficial do objeto atual MarshalByRefObject . (Herdado de MarshalByRefObject) |
| OpenExisting(String, SemaphoreRights) |
Abre o semáforo nomeado especificado, se já existir, com o acesso de segurança desejado. |
| OpenExisting(String) |
Abre o semáforo nomeado especificado, se este já existir. |
| Release() |
Sai do semáforo e devolve a contagem anterior. |
| Release(Int32) |
Sai do semáforo um número especificado de vezes e devolve a contagem anterior. |
| SetAccessControl(SemaphoreSecurity) |
Define a segurança de controlo de acesso para um semáforo de sistema nomeado. |
| ToString() |
Devolve uma cadeia que representa o objeto atual. (Herdado de Object) |
| TryOpenExisting(String, Semaphore) |
Abre o semáforo nomeado especificado, se este já existir, e devolve um valor que indica se a operação teve sucesso. |
| TryOpenExisting(String, SemaphoreRights, Semaphore) |
Abre o semáforo nomeado especificado, se já existir, com o acesso de segurança desejado, e devolve um valor que indica se a operação teve sucesso. |
| WaitOne() |
Bloqueia a linha de corrente até que a corrente WaitHandle receba um sinal. (Herdado de WaitHandle) |
| WaitOne(Int32, Boolean) |
Bloqueia o thread atual até que a corrente WaitHandle receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo e especificando se deve sair do domínio de sincronização antes da espera. (Herdado de WaitHandle) |
| WaitOne(Int32) |
Bloqueia a thread da corrente até que a corrente WaitHandle receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo em milissegundos. (Herdado de WaitHandle) |
| WaitOne(TimeSpan, Boolean) |
Bloqueia o thread atual até que a instância atual receba um sinal, usando a TimeSpan para especificar o intervalo de tempo e especificando se deve sair do domínio de sincronização antes da espera. (Herdado de WaitHandle) |
| WaitOne(TimeSpan) |
Bloqueia o thread atual até que a instância atual receba um sinal, usando a TimeSpan para especificar o intervalo de tempo. (Herdado de WaitHandle) |
Implementações de Interface Explícita
| Name | Description |
|---|---|
| IDisposable.Dispose() |
Esta API suporta a infraestrutura de produtos e não é pressuposta para ser utilizada diretamente a partir do seu código. Liberta todos os recursos utilizados pelo WaitHandle. (Herdado de WaitHandle) |
Métodos da Extensão
| Name | Description |
|---|---|
| GetSafeWaitHandle(WaitHandle) |
Obtém o handle seguro para um handle de espera nativo do sistema operativo. |
| SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Define um handle seguro para um handle de espera nativo do sistema operativo. |
Aplica-se a
Segurança de Thread
Este tipo é seguro para fios.
Ver também
- de threading gerenciado
- Semáforo