Partilhar via


Estruturas de dados de sincronização

O Concurrency Runtime fornece várias estruturas de dados que permitem sincronizar o acesso a dados compartilhados de vários threads. Essas estruturas de dados são úteis quando você compartilha dados que você modifica com pouca frequência. Um objeto de sincronização, por exemplo, uma seção crítica, faz com que outros threads esperem até que o recurso compartilhado esteja disponível. Portanto, se você usar esse objeto para sincronizar o acesso aos dados que são usados com freqüência, você pode perder a escalabilidade em seu aplicativo. A Biblioteca de Padrões Paralelos (PPL) fornece a classe concurrency::combinable , que permite compartilhar um recurso entre vários threads ou tarefas sem a necessidade de sincronização. Para obter mais informações sobre a combinable classe, consulte Contêineres e objetos paralelos.

Secções

Este tópico descreve os seguintes tipos de bloco de mensagens assíncronas em detalhes:

secção crítica

A classe concurrency::critical_section representa um objeto de exclusão mútua cooperativa que cede a outras tarefas em vez de interrompê-las. As seções críticas são úteis quando vários threads exigem acesso exclusivo de leitura e gravação a dados compartilhados.

A critical_section classe não é reentrante. O método concurrency::critical_section::lock lança uma exceção do tipo concurrency::improper_lock se for chamado pelo thread que já possui o bloqueio.

Métodos e Características

A tabela a seguir mostra os métodos importantes que são definidos pela critical_section classe.

Método Descrição
bloqueio Adquire a secção crítica. O contexto de chamada permanece bloqueado até adquirir a trava.
try_lock Tenta adquirir a seção crítica, mas não bloqueia.
desbloquear Libera a seção crítica.

[Topo]

bloqueio de leitor/escritor

A classe concurrency::reader_writer_lock fornece operações seguras de leitura/gravação em dados partilhados. Use bloqueios de leitor/gravador quando vários threads exigirem acesso de leitura simultâneo a um recurso compartilhado, mas raramente gravam nesse recurso compartilhado. Esta classe permite que apenas um thread tenha acesso de gravação a um objeto de cada vez.

A reader_writer_lock classe pode ter um desempenho melhor do que a critical_section classe porque um critical_section objeto adquire acesso exclusivo a um recurso compartilhado, o que impede o acesso de leitura simultânea.

Como a critical_section classe, a reader_writer_lock classe representa um objeto de exclusão mútua cooperativa que cede a outras tarefas em vez de antecipá-las.

Quando um thread que deve gravar em um recurso compartilhado adquire um bloqueio de leitor/gravador, outros threads que também devem acessar o recurso são bloqueados até que o gravador libere o bloqueio. A reader_writer_lock classe é um exemplo de um bloqueio de preferência de gravação , que é um bloqueio que desbloqueia escritores em espera antes de desbloquear leitores em espera.

Tal como a critical_section classe, a reader_writer_lock classe não é reentrante. Os métodos concurrency::reader_writer_lock::lock e concurrency::reader_writer_lock::lock_read lançam uma exceção de tipo improper_lock se forem chamados por um thread que já possui o bloqueio.

Observação

Como a reader_writer_lock classe não é reentrante, não é possível atualizar um bloqueio somente leitura para um bloqueio de leitor/gravador ou fazer o downgrade de um bloqueio de leitor/gravador para um bloqueio somente leitura. A execução de qualquer uma dessas operações produz um comportamento não especificado.

Métodos e Características

A tabela a seguir mostra os métodos importantes que são definidos pela reader_writer_lock classe.

Método Descrição
bloqueio Adquire acesso de leitura/escrita ao bloqueio.
try_lock Tenta obter acesso de leitura/escrita ao bloqueio, mas não bloqueia o processo.
lock_read Adquire acesso somente leitura ao bloqueio.
try_lock_read (tentar_bloquear_leitura) Tenta obter acesso só de leitura ao bloqueio, mas não bloqueia.
desbloquear Libera o bloqueio.

[Topo]

scoped_lock e scoped_lock_read

As critical_section classes e reader_writer_lock fornecem classes auxiliares aninhadas que simplificam a maneira como você trabalha com objetos de exclusão mútua. Essas classes auxiliares são conhecidas como bloqueios delimitados.

A critical_section classe contém a classe concorrência::critical_section::scoped_lock. O construtor adquire acesso ao objeto fornecido critical_section , o destruidor libera o acesso a esse objeto. A reader_writer_lock classe contém a classe concurrency::reader_writer_lock::scoped_lock, que se assemelha a critical_section::scoped_lock, exceto pelo fato de que gerencia o acesso de escrita ao objeto fornecido reader_writer_lock. A classe reader_writer_lock também contém a classe simultaneidade::reader_writer_lock::scoped_lock_read. Essa classe gerencia o acesso de leitura ao objeto fornecido reader_writer_lock .

Os bloqueios com escopo oferecem vários benefícios quando se está a trabalhar com critical_section e reader_writer_lock objetos manualmente. Normalmente, você aloca um bloqueio com escopo na pilha. Um bloqueio com escopo libera automaticamente o acesso ao seu objeto de exclusão mútua quando é destruído; portanto, você não desbloqueia manualmente o objeto subjacente. Isso é útil quando uma função contém várias return instruções. Os bloqueios com escopo também podem ajudá-lo a escrever código à prova de exceções. Quando uma throw instrução provoca o desenrolamento da pilha, o destrutor de qualquer bloqueio de âmbito ativo é chamado, e, portanto, o objeto de exclusão mútua é sempre corretamente libertado.

Observação

Ao usar as classes critical_section::scoped_lock, reader_writer_lock::scoped_lock e reader_writer_lock::scoped_lock_read, não liberte manualmente o acesso ao objeto de exclusão mútua subjacente. Isso pode colocar o tempo de execução em um estado inválido.

evento

A classe concurrency::event representa um objeto de sincronização cujo estado pode ser sinalizado ou não sinalizado. Ao contrário dos objetos de sincronização, como seções críticas, cuja finalidade é proteger o acesso a dados compartilhados, os eventos sincronizam o fluxo de execução.

A event classe é útil quando uma tarefa concluiu o trabalho para outra tarefa. Por exemplo, uma tarefa pode sinalizar a outra tarefa que leu dados de uma conexão de rede ou de um arquivo.

Métodos e Características

A tabela a seguir mostra vários dos métodos importantes que são definidos pela event classe.

Método Descrição
aguarde Aguarda que o evento seja sinalizado.
definido Coloca o evento no estado sinalizado.
redefinir Define o evento para o estado não sinalizado.
wait_for_multiple Aguarda que vários eventos sejam sinalizados.

Exemplo

Para obter um exemplo que mostra como usar a event classe, consulte Comparando estruturas de dados de sincronização com a API do Windows.

[Topo]

Comparando estruturas de dados de sincronização com a API do Windows
Compara o comportamento das estruturas de dados de sincronização com as fornecidas pela API do Windows.

Runtime de Concorrência
Descreve o Concurrency Runtime, que simplifica a programação paralela e contém links para tópicos relacionados.