Visão geral dos primitivos de sincronização
O .NET estrutura fornece uma variedade de primitivos de sincronização para controlar as interações de threads e evitar condições de corrida.Esses podem ser basicamente divididos em três categorias: operações de bloqueio, sinalização e interligadas.
As categorias não são organizadas e claramente definidas: Alguns mecanismos de sincronização têm características de várias categorias; eventos liberar um único thread em um time são funcionalmente sistema autônomo bloqueios; o versão do qualquer bloquear pode ser pensado sistema autônomo sistema autônomo operações de sinal; e interligadas podem ser usado para construir bloqueios.No entanto, as categorias são úteis ainda.
É importante lembrar que thread sincronização é cooperativa.Se um thread não usa um mecanismo de sincronização e acessa diretamente o recurso protegido, esse mecanismo de sincronização não pode ser efetivo.
O bloqueio
Bloqueios oferecem controle de um recurso para um thread por vez, ou para um número de segmentos especificado.Um segmento que solicita um bloquear exclusivo quando o bloquear está em uso bloqueia até que o bloquear se torne disponível.
Bloqueios exclusivo
A forma mais simples de bloqueio é o translation from VPE for Csharp lock demonstrativo)SyncLock no Visual Basic), que controla o acesso a um bloco de código. sistema autônomo um bloco é citado freqüentemente sistema autônomo uma seção crítica.The lock demonstrativo é implementada usando o Enter e Exit métodos para o Monitor classe e usa try…catch…finally para garantir que o bloquear será liberado.
Em geral, usando o lock demonstrativo para proteger pequenos blocos de código, nunca abrangendo mais de um único método, é a melhor maneira de usar o Monitor classe. Embora poderoso, o Monitor classe está sujeita a bloqueios órfãos e deadlocks.
Classe Monitor
The Monitor classe fornece funcionalidade adicional, que pode ser usada em conjunto com o lock demonstrativo:
The TryEnter método permite que um thread que está bloqueado aguardando o recurso desistir após um intervalo especificado. Ele retorna um valor booliano indicando êxito ou falha, que pode ser usada para detectar e evitar deadlocks potenciais.
The Wait método é chamado um thread em uma seção crítica. Ele oferece o controle de recurso e bloqueia até que o recurso esteja disponível novamente.
The Pulse e PulseAll métodos permitem que um thread que está prestes a liberar o bloquear ou para telefonar Wait Para inserir um ou mais threads na fila de pronta para que eles podem adquirir o bloquear.
Tempos limite de Wait sobrecargas de método que aguardando segmentos para escapar à fila de pronta.
The Monitor classe pode fornecer bloquear em vários domínios de aplicativo se o objeto usado para o bloquear é derivada da MarshalByRefObject.
Monitor tem thread afinidade. Ou seja, um thread que inseriu o monitor deve sair chamando Exit ou Wait.
The Monitor classe não é instantiable. Seus métodos são estático (Shared no Visual Basic) e agir de acordo com um objeto instantiable bloquear.
Para obter uma visão geral sobre conceitual, consulte Monitores.
Classe Mutex
Segmentos solicitam um Mutex chamando uma sobrecarga do seu WaitOne método. Sobrecargas com tempos limite são fornecidas, para permitir que segmentos para desistir da espera.Ao contrário de Monitor classe, um mutex pode ser local ou global. Mutexes global, também chamados nomeado mutexes, são visíveis em todo o sistema operacional e pode ser usados para sincronizar threads em vários domínios de aplicativos ou processos.Locais mutexes derivar de MarshalByRefObjecte podem ser usados nos limites do domínio do aplicativo.
Além disso, Mutex deriva da WaitHandle, que significa que pode ser usada com mecanismos de sinalização fornecidos pelo WaitHandle, sistema autônomo o WaitAll, WaitAny, e SignalAndWait métodos.
Como Monitor, Mutex tem thread afinidade. Ao contrário de Monitor, um Mutex é um objeto instantiable.
Para obter uma visão geral sobre conceitual, consulte Exclusões mútuas.
Outros bloqueios
Bloqueios não precisam ser exclusivo.Muitas vezes é útil permitir um número limitado de segmentos simultâneo acesso a um recurso.Semáforos e bloqueios de leitor-gravador foram projetados para controlar esse tipo de acesso a recursos em pool.
Classe ReaderWriterLock
The ReaderWriterLockSlim classe aborda o caso em que um thread que altera os dados, o gravador deve ter acesso exclusivo a um recurso. Quando o gravador não estiver ativo, qualquer número de leitores pode acesso recurso (por exemplo, ao chamar o EnterReadLock método). Quando um thread solicita acesso exclusivo, (por exemplo, ao chamar o EnterWriteLock método), as solicitações subseqüentes leitor bloqueiam até que todos os leitores existentes tenham saído do bloquear e o gravador tem inserido e sair do bloquear.
ReaderWriterLockSlim tem thread afinidade.
Para obter uma visão geral sobre conceitual, consulte Bloqueios de leitor-gravador.
Classe de sinal
The Semaphore classe permite que um número de segmentos para acessar um recurso especificado. Solicitando o bloco de recurso até que um thread libera o sinal de segmentos adicionais.
Como a Mutex classe, Semaphore deriva da WaitHandle. Além disso, como Mutex, um Semaphore pode ser local ou global. Ele pode ser usado nos limites do domínio do aplicativo.
Ao contrário de Monitor, Mutex, e ReaderWriterLock, Semaphore não tem afinidade de segmento. Isso significa que ele pode ser usado em situações em que um thread adquire o sinal e outro lança-lo.
Para obter uma visão geral sobre conceitual, consulte Semáforos.
Sinalização
A maneira mais simples de esperar um sinal de Outros segmento é chamar o Join método bloqueia até que o Outros thread seja concluída. Join tem duas sobrecargas que permitem que o thread bloqueado para interromper a espera após o transcurso de um intervalo especificado.
Identificadores de espera fornecem um conjunto de espera e sinalização de recursos muito mais sofisticado.
Identificadores de Espera
Identificadores de espera derivam o WaitHandle classe, que por sua vez, deriva de MarshalByRefObject. Assim, os identificadores de espera podem ser usados para sincronizar as atividades de threads nos limites do domínio do aplicativo.
Bloco de threads em identificadores de espera, chamando o método de instância WaitOne ou um dos métodos estático WaitAll, WaitAny, ou SignalAndWait. Como eles são lançados depende de qual método foi chamado e o tipo de identificadores de espera.
Para obter uma visão geral sobre conceitual, consulte Identificadores de Espera.
Identificadores de espera de evento
Identificadores de espera do evento incluem o EventWaitHandle classe e suas classes derivadas, AutoResetEvent e ManualResetEvent. Segmentos são liberados de um identificador de espera do evento quando o identificador de espera do evento é sinalizado chamando seus Set método ou usando o SignalAndWait método.
Evento de espera alças ou reiniciar próprios automaticamente, como um turnstile permite apenas um thread por meio de cada vez que ele é sinalizado ou deve ser redefinido manualmente, como uma entrada é fechada até sinalizado e, em seguida, abra até que alguém feche.sistema autônomo seus nomes já dizem, AutoResetEvent e ManualResetEvent representam o primeiro e segundo, respectivamente.
An EventWaitHandle pode representar qualquer tipo de evento e pode ser local ou global. As classes derivadas AutoResetEvent e ManualResetEvent sempre são locais.
Identificadores de espera do evento não tem thread afinidade.Qualquer thread pode sinalizar um identificador de espera do evento.
Para obter uma visão geral sobre conceitual, consulte EventWaitHandle AutoResetEvent e ManualResetEvent.
Mutex e Classes sinal
Porque o Mutex e Semaphore classes de derivar WaitHandle, eles podem ser usados com os métodos estático da WaitHandle. Por exemplo, um thread pode usar o WaitAll método aguardar até que todos os três seguintes forem verdadeiras: an EventWaitHandle está sinalizado, uma Mutex é liberado e um Semaphore é liberada. Da mesma forma, um thread pode usar o WaitAny método para esperar a qualquer uma dessas condições é verdadeiro.
Para um Mutex ou um Semaphore, que está sendo sinalizado significa sendo lançada. Se o tipo é usado sistema autônomo o primeiro argumento do SignalAndWait método, que ele seja liberado. No caso de um Mutex, que tem afinidade de thread, uma exceção é lançada se o thread de chamada não possuir o mutex. Conforme observado anteriormente, semáforos não têm thread afinidade.
Operações interligadas
Operações interligadas são simples atômica operações realizadas em um local de memória por métodos estático do Interlocked classe. Essas operações atômicas incluem adição, incrementam e decrementam, exchange, troca condicional dependendo de uma comparação e operações para valores de 64 bit em plataformas de 32 bit de leitura.
Observação: |
---|
A garantia de atomicidade está limitada a operações individuais; quando várias operações devem ser executadas sistema autônomo uma unidade, um mecanismo de sincronização mais refinado deve ser usado. |
Embora nenhuma dessas operações bloqueios ou sinais, eles podem ser usados para construir bloqueios e sinais.Como são nativo do sistema operacional Windows, operações interligadas são extremamente rápidas.
Operações interligadas podem ser usadas com garantias de memória volátil para escrever aplicativos que exibem simultaneidade eficiente sem bloqueio, entretanto, eles exigem programação nível sofisticada, baixa e para a maioria das finalidades bloqueios simples são a melhor opção.
Para obter uma visão geral sobre conceitual, consulte Operações interligadas.
Consulte também
Conceitos
Sincronizando dados para o multithreading