Regras para encontrar / evitando dados compartilhados em um aplicativo com vários segmentos
-
03-07-2019 - |
Pergunta
Hy,
como todos sabemos, o desenvolvimento de um aplicativo de multithreading é uma coisa difícil. Especialmente o ponto quando eo que bloqueio não é IMHO tão óbvio. Muitas vezes eu estou olhando para um método / classe e devo me perguntar, se eu compartilhar alguns dados, que podem ser modificados por vários segmentos. E quando eu não tenho certeza que ele termina em um lock () ao longo de um bloco de código inteiro.
Então, o que eu gostaria de saber: você tem sugestões para padrões / regras etc., para identificar dados compartilhados? Ou técnicas para garantir que seu código é thread-safe.
por exemplo:.
-
métodos
- estáticos não deve modificar os campos da classe. (A menos que eles bloquear o campo.)
- Referência type'd parâmetros de um método não deve ser passado "diretamente". Sempre passar um clone.
A propósito:
Microsoft Research está trabalhando em XADREZ . Uma ferramenta para encontrar e reproduzir Heisenbugs em programas concorrentes. Espero que este e PLINQ fará melhorar o desenvolvimento de programas concorrentes.
Solução
Sempre que possível, faça seus tipos imutáveis ??para começar. Então não há necessidade de clone. Se você precisa de "mudança" o conteúdo de um objeto, fazer o método retornar um novo objeto em vez -. Exatamente como String.Replace
etc faz
Este é basicamente o estilo de programação funcional, e é lindo. É lamentável que nós não (atualmente) têm coleções imutáveis ??construído na plataforma .NET, Althoughthere são aquelas de terceiros ao redor, incluindo um por nossa própria JaredPar .
Outras dicas
O encapsulamento de dados em uma classe é útil quando tornando-se o segmento de seguros. Você ganha controle sobre como os dados são acessados, e você pode fazer a classe responsável pela sincronização em vez de ter código de todo o aplicativo tentando sincronizar corretamente.
Além disso, você tem um lugar para colocar uma variável privada que você pode usar como identificador de bloqueio, de modo que você pode evitar o uso de dados em si como identificador para o bloqueio. Por ter uma variável privada dedicada como bloqueio de identificador de remover uma possível fonte de impasses.