Partilhar via


Anotando o comportamento de bloqueio

Para evitar bug de simultaneidade em seu programa multi-threaded, sempre siga uma disciplina apropriado de bloqueio e usar anotações de SAL.

Os bug de simultaneidade são difíceis de notòria reproduzir, diagnosticar, e depurar porque não são determinísticas.Raciocinar sobre a intercalação de thread é difícil o melhor forma, e se torna impraticável quando você estiver criando um corpo de código que tem mais do que alguns threads.Consequentemente, é uma prática recomendada e uma disciplina de bloqueio em seus programas multi-threaded.Por exemplo, obedecendo um bloqueio ordenar ao adquirir vários bloqueios que ajuda a evitar deadlocks, e a aquisição do bloqueio apropriado de guarda antes de acessar ajuda compartilhadas de um recurso evitar situações de competição.

Infelizmente, as regras aparentemente simples de bloqueio podem ser surpreendentemente duras de e na prática.Uma limitação fundamental nas linguagens de programação de hoje e em compiladores é que eles não suportam diretamente a especificação e análise de requisitos de simultaneidade.Os programadores precisam confiar em comentários informais de código para expressar suas intenções sobre como usam bloqueios.

As anotações de SAL de simultaneidade são criadas para ajudá-lo a especificar efeitos colaterais de bloqueio, responsabilidade de bloqueio, tutela de dados, a hierarquia de pedido de bloqueio, e outro comportamento de bloqueio esperado.Fazendo regras implícitas explícitas, as anotações de simultaneidade de SAL fornecem uma maneira consistente para que você documente como o código usa regras de bloqueio.As anotações de simultaneidade também aprimoram a capacidade de ferramentas de análise de código de localizar situações de competição, deadlock, operações incompatíveis de sincronização, e outros erros suteis de simultaneidade.

Diretrizes gerais

Usando anotações, você poderá indicar os contratos que são implícitos por definições de funções entre implementações callees () e clientes chamadores (), e express invariants e outras propriedades de programa que pode mais melhorar a análise.

O SAL oferece suporte a diversos tipos de bloqueio primitivo- por exemplo, seções críticas, mutexes, bloqueios de rotação, entre outros objetos do recurso.Muitas anotações de simultaneidade têm uma expressão de bloqueio como um parâmetro.Por convenção, um bloqueio é denotado pela expressão de caminho do objeto de bloqueio subjacente.

Alguns thread regras de propriedade para serem considerados:

  • Os bloqueios de rotação são os bloqueios uncounted com propriedade leve do thread.

  • Mutexes e seções críticos os bloqueios são contados com propriedade leve do thread.

  • Semáforos e os eventos são contados os bloqueios que não têm a propriedade leve do thread.

Anotações de Bloqueio

A tabela a seguir lista as anotações de bloqueio.

Anotação

Descrição

_Acquires_exclusive_lock_(expr)

Anota uma função e indica que o estado da postagem os incrementos de função por um a contagem exclusiva de bloqueio do objeto de bloqueio que é nomeada por expr.

_Acquires_lock_(expr)

Anota uma função e indica que o estado da postagem os incrementos de função por um a contagem de bloqueio do objeto de bloqueio que é nomeada por expr.

_Acquires_nonreentrant_lock_(expr)

O bloqueio que é nomeada por expr é adquirido. Um erro é informado se o bloqueio for mantido nele.

_Acquires_shared_lock_(expr)

Anota uma função e indica que o estado da postagem os incrementos de função por um a contagem compartilhada de bloqueio do objeto de bloqueio que é nomeada por expr.

_Create_lock_level_(name)

Uma instrução que declara o símbolo name para ser um nível de bloqueio de forma que pode ser usado nas anotações _Has_Lock_level_ e _Lock_level_order_.

_Has_lock_kind_(kind)

Anota qualquer objeto para refinar a informação de tipo de um objeto de recurso.Às vezes, um tipo comum é usado para tipos diferentes de recursos e o tipo sobrecarregado não é suficiente para distinguir os requisitos de semântica entre vários recursos.Eis uma lista de parâmetros predefinidos de kind :

_Lock_kind_mutex_

Identificação do tipo de bloqueio para mutexes.

_Lock_kind_event_

Identificação do tipo de bloqueio para eventos.

_Lock_kind_semaphore_

Identificação do tipo de bloqueio para semáforos.

_Lock_kind_spin_lock_

Identificação do tipo de bloqueio para bloqueios de rotação.

_Lock_kind_critical_section_

Identificação do tipo de bloqueio para seções críticas.

_Has_lock_level_(name)

Anota um objeto de bloqueio e permite bloqueio em nível de name.

_Lock_level_order_(name1, name2)

Uma declaração que dá a ordenação de bloqueio entre name1 e name2.

_Post_same_lock_(expr1, expr2)

Anota uma função e indica que o estado da postagem os dois bloqueios, expr1 e expr2, será tratado como se forem o mesmo objeto de bloqueio.

_Releases_exclusive_lock_(expr)

Anota uma função e indica que o estado da postagem reduz a função por uma contagem exclusiva de bloqueio do objeto de bloqueio que é nomeada por expr.

_Releases_lock_(expr)

Anota uma função e indica que o estado da postagem do diminuirá a contagem por uma função de bloqueio do objeto de bloqueio que é nomeada por expr.

_Releases_nonreentrant_lock_(expr)

O bloqueio que é nomeada por expr é liberado.Um erro é informado se o bloqueio não é mantido no momento.

_Releases_shared_lock_(expr)

Anota uma função e indica que o estado da postagem reduz a função por uma contagem compartilhada de bloqueio do objeto de bloqueio que é nomeada por expr.

_Requires_lock_held_(expr)

Anota uma função e indica-a que indica pre em que a contagem de bloqueio do objeto que é nomeada por expr é pelo menos um.

_Requires_lock_not_held_(expr)

Anota uma função e indica-a que indica pre em que a contagem de bloqueio do objeto que é nomeada por expr são zero.

_Requires_no_locks_held_

Anota uma função e indica que as contagens de bloqueio de todos os bloqueios que são conhecidos ao verificador são zero.

_Requires_shared_lock_held_(expr)

Anota uma função e indica-a que indica pre em que a conta compartilhada de bloqueio do objeto que é nomeada por expr é pelo menos um.

_Requires_exclusive_lock_held_(expr)

Anota uma função e indica-a que indica pre em que a contagem exclusiva de bloqueio do objeto que é nomeada por expr é pelo menos um.

Intrinsics de SAL para objetos não expostos de bloqueio

Certos objetos de bloqueio não são expostos pela implementação das funções de bloqueio associadas. A tabela a seguir lista as variáveis intrínsecos de SAL que habilitam anotações em funções que operam nesses objetos não expostos de bloqueio.

Anotação

Descrição

_Global_cancel_spin_lock_

Descreve o bloqueio de rotação de cancelamento.

_Global_critical_region_

Descreve a região crítico.

_Global_interlock_

Descreve bloqueado operações.

_Global_priority_region_

Descreve a região de prioridade.

Anotações de Acesso a Dados Compartilhados

A tabela a seguir lista as anotações para o acesso a dados compartilhado.

Anotação

Descrição

_Guarded_by_(expr)

Anota uma variável e indica que sempre que a variável é acessado, a contagem de bloqueio do objeto de bloqueio que é nomeada por expr é pelo menos um.

_Interlocked_

Anota uma variável e é equivalente a _Guarded_by_(_Global_interlock_).

_Interlocked_operand_

O parâmetro de função anotado é o operando de destino de uma das várias funções interconectadas. Esses operandos devem ter propriedades adicionais específicas.

_Write_guarded_by_(expr)

Anota uma variável e indica que sempre que a variável é alterado, a contagem de bloqueio do objeto de bloqueio que é nomeada por expr é pelo menos um.

Consulte também

Referência

Anotando parâmetros de função e valores de retorno

Anotando o comportamento da função

Anotando estruturas e classes

Especificando quando e onde uma anotação se aplica

Funções intrínsecas

Práticas recomendadas e exemplos (SAL)

Conceitos

Noções básicas de SAL

Outros recursos

Usando anotações de SAL para reduzir defeitos de código do C/C++

Blog da equipe de análise de código