Visão geral dos primitivos de sincronizaçãoOverview of synchronization primitives

O .NET fornece uma variedade de tipos que você pode usar para sincronizar o acesso a um recurso compartilhado ou coordenar a interação de thread..NET provides a range of types that you can use to synchronize access to a shared resource or coordinate thread interaction.

Importante

Use a mesma instância de primitivos de sincronização para proteger o acesso de um recurso compartilhado.Use the same synchronization primitive instance to protect access of a shared resource. Se usar instâncias primitivas de sincronização diferentes para proteger o mesmo recurso, você evitará a proteção fornecida por um primitivo de sincronização.If you use different synchronization primitive instances to protect the same resource, you'll circumvent the protection provided by a synchronization primitive.

Tipos de sincronização leve e a classe WaitHandleWaitHandle class and lightweight synchronization types

Vários primitivos de sincronização .NET derivam da classe System.Threading.WaitHandle, que encapsula um identificador de sincronização do sistema operacional nativo e usa um mecanismo de sinalização de interação de thread.Multiple .NET synchronization primitives derive from the System.Threading.WaitHandle class, which encapsulates a native operating system synchronization handle and uses a signaling mechanism for thread interaction. Essas classes incluem:Those classes include:

No .NET Framework, porque WaitHandle deriva de System.MarshalByRefObject, esses tipos podem ser usados para sincronizar as atividades de threads entre limites de domínio de aplicativo.In the .NET Framework, because WaitHandle derives from System.MarshalByRefObject, these types can be used to synchronize the activities of threads across application domain boundaries.

No .NET Framework e no .NET Core, alguns desses tipos podem representar os identificadores de sincronização de sistema nomeado, que são visíveis em todo o sistema operacional e podem ser usados para a sincronização entre processos:In the .NET Framework and .NET Core, some of these types can represent named system synchronization handles, which are visible throughout the operating system and can be used for the inter-process synchronization:

  • Mutex (.NET Framework e .NET Core),Mutex (.NET Framework and .NET Core),
  • Semaphore (.NET Framework e .NET Core no Windows),Semaphore (.NET Framework and .NET Core on Windows),
  • EventWaitHandle (.NET Framework e .NET Core no Windows).EventWaitHandle (.NET Framework and .NET Core on Windows).

Para obter mais informações, veja a referência de API WaitHandle.For more information, see the WaitHandle API reference.

Tipos de sincronização leve não dependem de identificadores do sistema operacional subjacente e normalmente fornecem um melhor desempenho.Lightweight synchronization types don't rely on underlying operating system handles and typically provide better performance. No entanto, não podem ser usados para a sincronização entre processos.However, they cannot be used for the inter-process synchronization. Use esses tipos para sincronização de thread dentro de um aplicativo.Use those types for thread synchronization within one application.

Alguns desses tipos são alternativas aos tipos derivados de WaitHandle.Some of those types are alternatives to the types derived from WaitHandle. Por exemplo, SemaphoreSlim é uma alternativa leve para Semaphore.For example, SemaphoreSlim is a lightweight alternative to Semaphore.

Sincronização de acesso a um recurso compartilhadoSynchronization of access to a shared resource

O .NET fornece uma variedade de primitivos de sincronização para controlar o acesso a um recurso compartilhado por vários threads..NET provides a range of synchronization primitives to control access to a shared resource by multiple threads.

Classe MonitorMonitor class

A classe System.Threading.Monitor concede acesso mutuamente exclusivo em um recurso compartilhado, adquirindo ou liberando um bloqueio no objeto que identifica o recurso.The System.Threading.Monitor class grants mutually exclusive access to a shared resource by acquiring or releasing a lock on the object that identifies the resource. Embora um bloqueio seja mantido, o thread que mantém o bloqueio pode adquiri-lo novamente e liberá-lo.While a lock is held, the thread that holds the lock can again acquire and release the lock. Qualquer outro thread é impedido de adquirir o bloqueio e o método Monitor.Enter aguardará até que o bloqueio seja liberado.Any other thread is blocked from acquiring the lock and the Monitor.Enter method waits until the lock is released. O método Enter adquire um bloqueio liberado.The Enter method acquires a released lock. Você também pode usar o método Monitor.TryEnter para especificar o tempo durante o qual um thread tenta adquirir um bloqueio.You can also use the Monitor.TryEnter method to specify the amount of time during which a thread attempts to acquire a lock. Porque a classe Monitor tem afinidade de thread, o thread que adquiriu um bloqueio deve liberar o bloqueio chamando o método Monitor.Exit.Because the Monitor class has thread affinity, the thread that acquired a lock must release the lock by calling the Monitor.Exit method.

Você pode coordenar a interação de threads que adquirirem um bloqueio no mesmo objeto usando os métodos Monitor.Wait, Monitor.Pulse e Monitor.PulseAll.You can coordinate the interaction of threads that acquire a lock on the same object by using the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

Para obter mais informações, veja a referência de API Monitor.For more information, see the Monitor API reference.

Observação

Use a instrução lock no C# e a instrução SyncLock no Visual Basic para sincronizar o acesso a um recurso compartilhado, em vez de usar a classe Monitor diretamente.Use the lock statement in C# and the SyncLock statement in Visual Basic to synchronize access to a shared resource instead of using the Monitor class directly. Essas instruções são implementadas usando os métodos Enter e Exit e um bloco try…finally para garantir que o bloqueio adquirido sempre seja liberado.Those statements are implemented by using the Enter and Exit methods and a try…finally block to ensure that the acquired lock is always released.

Classe MutexMutex class

A classe System.Threading.Mutex, como Monitor, concede acesso exclusivo a um recurso compartilhado.The System.Threading.Mutex class, like Monitor, grants exclusive access to a shared resource. Use uma das sobrecargas do método Mutex.WaitOne para solicitar a propriedade de um mutex.Use one of the Mutex.WaitOne method overloads to request the ownership of a mutex. Como Monitor, Mutex tem afinidade de thread e o thread que adquiriu um mutex deverá liberá-lo chamando o método Mutex.ReleaseMutex.Like Monitor, Mutex has thread affinity and the thread that acquired a mutex must release it by calling the Mutex.ReleaseMutex method.

Diferente de Monitor, a classe Mutex pode ser usada para sincronização entre processos.Unlike Monitor, the Mutex class can be used for inter-process synchronization. Para fazer isso, use um mutex nomeado, que fica visível em todo o sistema operacional.To do that, use a named mutex, which is visible throughout the operating system. Para criar uma instância de mutex nomeada, use um construtor Mutex que especifique um nome.To create a named mutex instance, use a Mutex constructor that specifies a name. Você também pode Mutex.OpenExisting chamar o método para abrir um mutex de sistema nomeado existente.You can also call the Mutex.OpenExisting method to open an existing named system mutex.

Para obter mais informações, veja o artigo Mutexes e a referência da API Mutex.For more information, see the Mutexes article and the Mutex API reference.

Estrutura de SpinLockSpinLock structure

A estrutura System.Threading.SpinLock, como Monitor, concede acesso exclusivo a um recurso compartilhado com base na disponibilidade de um bloqueio.The System.Threading.SpinLock structure, like Monitor, grants exclusive access to a shared resource based on the availability of a lock. Quando SpinLock tenta adquirir um bloqueio que não está disponível, ele aguarda em um loop, verificando repetidamente até o bloqueio ficar disponível.When SpinLock attempts to acquire a lock that is unavailable, it waits in a loop, repeatedly checking until the lock becomes available.

Para obter mais informações sobre as vantagens e as desvantagens do uso do bloqueio de rotação, veja o artigo SpinLock e a referência da API SpinLock.For more information about the benefits and drawbacks of using spin lock, see the SpinLock article and the SpinLock API reference.

Classe ReaderWriterLockSlimReaderWriterLockSlim class

A classe System.Threading.ReaderWriterLockSlim concede acesso exclusivo a um recurso compartilhado para gravação e permite que vários threads acessem o recurso simultaneamente para leitura.The System.Threading.ReaderWriterLockSlim class grants exclusive access to a shared resource for writing and allows multiple threads to access the resource simultaneously for reading. Você talvez queira usar ReaderWriterLockSlim para sincronizar o acesso a uma estrutura de dados compartilhada que dá suporte a operações de leitura thread-safe, mas requer acesso exclusivo para realizar a operação de gravação.You might want to use ReaderWriterLockSlim to synchronize access to a shared data structure that supports thread-safe read operations, but requires exclusive access to perform write operation. Quando um thread solicita acesso exclusivo (por exemplo, ao chamar o método ReaderWriterLockSlim.EnterWriteLock), o leitor subsequente solicita o bloqueio até que todos os leitores e gravadores existentes tenham saído do bloqueio e o gravador tenha entrado e saído do bloqueio.When a thread requests exclusive access (for example, by calling the ReaderWriterLockSlim.EnterWriteLock method), subsequent reader and writer requests block until all existing readers have exited the lock, and the writer has entered and exited the lock.

Para obter mais informações, veja a referência de API ReaderWriterLockSlim.For more information, see the ReaderWriterLockSlim API reference.

Classes Semaphore e SemaphoreSlimSemaphore and SemaphoreSlim classes

As classes System.Threading.Semaphore e System.Threading.SemaphoreSlim limitam o número de threads que podem acessar um recurso compartilhado ou um pool de recursos simultaneamente.The System.Threading.Semaphore and System.Threading.SemaphoreSlim classes limit the number of threads that can access a shared resource or a pool of resources concurrently. Threads adicionais que solicitam o recurso aguardam até que qualquer thread liberar o semáforo.Additional threads that request the resource wait until any thread releases the semaphore. Como o semáforo não tem afinidade de thread, um thread pode adquirir o semáforo e outro pode liberá-lo.Because the semaphore doesn't have thread affinity, a thread can acquire the semaphore and another one can release it.

SemaphoreSlim é uma alternativa leve a Semaphore e pode ser usado somente para sincronização dentro do limite de um único processo.SemaphoreSlim is a lightweight alternative to Semaphore and can be used only for synchronization within a single process boundary.

No Windows, você pode usar Semaphore para a sincronização entre processos.On Windows, you can use Semaphore for the inter-process synchronization. Para fazer isso, crie uma instância Semaphore que representa um semáforo de sistema nomeado usando um dos Construtores de semáforo que especifica um nome ou o método Semaphore.OpenExisting.To do that, create a Semaphore instance that represents a named system semaphore by using one of the Semaphore constructors that specifies a name or the Semaphore.OpenExisting method. SemaphoreSlim não dá suporte a sinais de sistema nomeado.SemaphoreSlim doesn't support named system semaphores.

Para obter mais informações, veja o artigo Semaphore e SemaphoreSlim e a referência à API Semaphore ou SemaphoreSlim.For more information, see the Semaphore and SemaphoreSlim article and the Semaphore or SemaphoreSlim API reference.

Interação ou sinalização de threadThread interaction, or signaling

Interação de thread (ou sinalização do thread) significa que um thread deve aguardar notificação ou um sinal de um ou mais threads para continuar.Thread interaction (or thread signaling) means that a thread must wait for notification, or a signal, from one or more threads in order to proceed. Por exemplo, se o thread A chamar o método Thread.Join do thread B, o thread A será bloqueado até que o thread B seja concluído.For example, if thread A calls the Thread.Join method of thread B, thread A is blocked until thread B completes. Os primitivos de sincronização descritos na seção anterior fornecem um mecanismo diferente para sinalização: ao liberar um bloqueio, um thread notifica outro thread de que ele pode continuar adquirindo o bloqueio.The synchronization primitives described in the preceding section provide a different mechanism for signaling: by releasing a lock, a thread notifies another thread that it can proceed by acquiring the lock.

Esta seção descreve outras construções de sinalização fornecidas pelo .NET.This section describes additional signaling constructs provided by .NET.

Classes EventWaitHandle, AutoResetEvent, ManualResetEvent e ManualResetEventSlimEventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim classes

A classe System.Threading.EventWaitHandle representa um evento de sincronização de thread.The System.Threading.EventWaitHandle class represents a thread synchronization event.

Um evento de sincronização pode estar em um estado não sinalizado ou sinalizado.A synchronization event can be either in an unsignaled or signaled state. Quando o estado de um evento não é sinalizado, um thread que chama a sobrecarga WaitOne do evento é bloqueado até que um evento seja sinalizado.When the state of an event is unsignaled, a thread that calls the event's WaitOne overload is blocked until an event is signaled. O método EventWaitHandle.Set define o estado de um evento como sinalizado.The EventWaitHandle.Set method sets the state of an event to signaled.

O comportamento de um EventWaitHandle que foi assinalado depende de seu modo de redefinição:The behavior of an EventWaitHandle that has been signaled depends on its reset mode:

No Windows, você pode usar EventWaitHandle para a sincronização entre processos.On Windows, you can use EventWaitHandle for the inter-process synchronization. Para fazer isso, crie uma instância EventWaitHandle que representa um evento de sincronização do sistema nomeado usando um dos construtores EventWaitHandle que especificam um nome ou o método EventWaitHandle.OpenExisting.To do that, create a EventWaitHandle instance that represents a named system synchronization event by using one of the EventWaitHandle constructors that specifies a name or the EventWaitHandle.OpenExisting method.

Para obter mais informações, confira o artigo EventWaitHandle.For more information, see the EventWaitHandle article. Para a referência de API, veja EventWaitHandle, AutoResetEvent, ManualResetEvent e ManualResetEventSlim.For the API reference, see EventWaitHandle, AutoResetEvent, ManualResetEvent, and ManualResetEventSlim.

Classe CountdownEventCountdownEvent class

A classe System.Threading.CountdownEvent representa um evento definido quando a contagem é zero.The System.Threading.CountdownEvent class represents an event that becomes set when its count is zero. Embora CountdownEvent.CurrentCount seja maior que zero, um thread que chama CountdownEvent.Wait é bloqueado.While CountdownEvent.CurrentCount is greater than zero, a thread that calls CountdownEvent.Wait is blocked. Chame CountdownEvent.Signal para diminuir a contagem de um evento.Call CountdownEvent.Signal to decrement an event's count.

Em contraste com ManualResetEvent ou ManualResetEventSlim, que você pode usar para desbloquear vários threads com um sinal de um thread, você pode usar CountdownEvent para desbloquear um ou mais threads com sinais de vários threads.In contrast to ManualResetEvent or ManualResetEventSlim, which you can use to unblock multiple threads with a signal from one thread, you can use CountdownEvent to unblock one or more threads with signals from multiple threads.

Para obter mais informações, veja o artigo CountdownEvent e a referência à API CountdownEvent.For more information, see the CountdownEvent article and the CountdownEvent API reference.

Classe de barreiraBarrier class

A classe System.Threading.Barrier representa uma barreira de execução do thread.The System.Threading.Barrier class represents a thread execution barrier. Um thread que chama o método Barrier.SignalAndWait sinaliza que atingiu a barreira e aguarda até que outros threads participantes atinjam a barreira.A thread that calls the Barrier.SignalAndWait method signals that it reached the barrier and waits until other participant threads reach the barrier. Quando todos os threads participantes atingem a barreira, eles prosseguem e a barreira é redefinida e pode ser usada novamente.When all participant threads reach the barrier, they proceed and the barrier is reset and can be used again.

Você pode usar Barrier quando um ou mais threads exigirem os resultados de outros threads antes de prosseguir para a próxima fase de cálculo.You might use Barrier when one or more threads require the results of other threads before proceeding to the next computation phase.

Para obter mais informações, veja o artigo Barreira e a referência da API Barrier.For more information, see the Barrier article and the Barrier API reference.

Classe InterlockedInterlocked class

A classe System.Threading.Interlocked fornece métodos estáticos que executam operações atômicas simples em uma variável.The System.Threading.Interlocked class provides static methods that perform simple atomic operations on a variable. Essas operações atômicas incluem adição, incremento e decremento, troca e troca condicional que depende de uma comparação e operação de leitura de um valor inteiro de 64 bits.Those atomic operations include addition, increment and decrement, exchange and conditional exchange that depends on a comparison, and read operation of a 64-bit integer value.

Para obter mais informações, veja a referência de API Interlocked.For more information, see the Interlocked API reference.

Estrutura SpinWaitSpinWait structure

A estrutura System.Threading.SpinWait oferece suporte para espera baseada em rotação.The System.Threading.SpinWait structure provides support for spin-based waiting. Você pode usá-la quando um thread tiver de esperar pela sinalização de um evento ou por uma condição específica. No entanto, quando o tempo de espera real for menor do que o tempo necessário, use um identificador de espera ou bloqueie o thread.You might want to use it when a thread has to wait for an event to be signaled or a condition to be met, but when the actual wait time is expected to be less than the waiting time required by using a wait handle or by otherwise blocking the thread. Usando o SpinWait, você pode especificar um curto período de tempo para girar enquanto espera e, em seguida, gerar (por exemplo, aguardando ou em espera) somente se a condição não for atendida no tempo especificado.By using SpinWait, you can specify a short period of time to spin while waiting, and then yield (for example, by waiting or sleeping) only if the condition was not met in the specified time.

Para obter mais informações, veja o artigo SpinWait e a referência da API SpinWait.For more information, see the SpinWait article and the SpinWait API reference.

Confira tambémSee also