O livro "Competitividade e simultaneidade na plataforma .NET. Padrões de design eficazes ”

imagem Oi, habrozhiteli! O livro de Riccardo Terrell fornece orientações sobre como criar programas competitivos e escaláveis ​​no .NET, destacando os benefícios de um paradigma funcional e fornecendo as ferramentas e os princípios apropriados para competir de maneira fácil e correta. Como resultado, munido de novas habilidades, você receberá o conhecimento necessário para se tornar um especialista no fornecimento de soluções bem-sucedidas de alto desempenho.

Se você estiver escrevendo código multithread no .NET, este livro pode ajudá-lo. Se você estiver interessado em usar um paradigma funcional para simplificar a programação competitiva e maximizar o desempenho do aplicativo, este livro será um guia importante para você. Beneficiará qualquer desenvolvedor .NET que queira criar aplicativos competitivos, reativos e assíncronos que escalem e se adaptam automaticamente aos recursos de hardware disponíveis onde quer que esses programas funcionem.

Estrutura da publicação: roteiro


Os catorze capítulos deste livro estão divididos em três partes. A Parte I apresenta os conceitos funcionais da programação competitiva e descreve as habilidades necessárias para entender os aspectos funcionais da escrita de programas multithread.

  • O capítulo 1 descreve os conceitos e objetivos básicos da programação competitiva, bem como as razões para usar a programação funcional para escrever aplicativos multithread.
  • O capítulo 2 explora uma variedade de tecnologias de programação funcional para melhorar o desempenho de aplicativos multithread. O objetivo deste capítulo é fornecer ao leitor os conceitos usados ​​no restante do livro e introduzir idéias poderosas que surgem de um paradigma funcional.
  • O capítulo 3 fornece uma visão geral do conceito funcional de imutabilidade. Explica como a imutabilidade é usada para escrever programas competitivos previsíveis e corretos e para implementar estruturas de dados funcionais que são de natureza segura para threads.

Na parte II, vários modelos de programação competitiva em um paradigma funcional são examinados em profundidade. Vamos explorar tópicos como a Task Parallel Library (TPL) e implementar padrões paralelos como Bifurcação / Junção, dividir e conquistar e MapReduce. Esta seção também discute o layout declarativo, abstrações de alto nível em operações assíncronas, programação de agentes e semântica de transferência de mensagens.

  • O capítulo 4 descreve os conceitos básicos do processamento paralelo de grandes quantidades de dados, incluindo modelos como Fork / Join.
  • O Capítulo 5 apresenta métodos mais sofisticados para processamento paralelo de grandes quantidades de informações, como agregação paralela, redução de dados e implementação de um modelo MapReduce paralelo.
  • O Capítulo 6 fornece informações detalhadas sobre os métodos funcionais para processar fluxos de eventos (dados) em tempo real, usando operadores funcionais de alta ordem nas Extensões Reativas do .NET para formar combinadores assíncronos de eventos. Os métodos estudados serão então utilizados para implementar um modelo reativo de editor-assinante competitivo.
  • O Capítulo 7 fornece uma explicação do modelo de programação baseado em tarefas, aplicado à programação funcional para implementar operações competitivas usando o modelo Monadic. Em seguida, esse método é usado para criar um pipeline competitivo baseado em um paradigma de programação funcional.
  • O capítulo 8 é dedicado à implementação da computação paralela ilimitada usando o modelo de programação assíncrona em C #. Este capítulo também discute métodos de tratamento de erros e métodos para construir operações assíncronas.
  • O capítulo 9 descreve o fluxo de trabalho assíncrono em F #. Ele mostra como uma avaliação adiada e explícita nesse modelo permite uma semântica composicional mais alta. Em seguida, aprenderemos como implementar expressões computacionais personalizadas para aumentar o nível de abstração para a programação declarativa.
  • O capítulo 10 mostra como, com base no conhecimento adquirido nos capítulos anteriores, combinadores e modelos, como Functor, Monad e Applicative, podem ser implementados para compor e executar várias operações assíncronas e lidar com erros sem efeitos colaterais.
  • O capítulo 11 analisa a programação reativa usando um modelo de mensagens de software. Revela o conceito de isolamento natural como uma tecnologia que complementa a imutabilidade e permite a criação de programas competitivos. Este capítulo se concentra na classe MailboxProcessor usada no F # para distribuir o trabalho paralelo usando a programação de agentes e uma abordagem sem recursos.
  • O capítulo 12 descreve a programação de agentes usando a biblioteca TPL Dataflow do .NET com exemplos em C #. Ele mostra como implementar agentes sem estado e sem estado em C #, bem como executar vários cálculos em paralelo que trocam dados entre si, usando (enviando) mensagens no estilo de um pipeline.

A parte III mostra como colocar em prática todos os métodos funcionais de programação competitiva estudados nos capítulos anteriores.

  • O capítulo 13 apresenta um conjunto de receitas úteis para resolver problemas competitivos complexos, retirados da prática real. Essas receitas usam todos os padrões funcionais descritos neste livro.
  • O capítulo 14 descreve um aplicativo completo desenvolvido e implementado usando modelos e métodos competitivos funcionais estudados neste livro. Você criará um aplicativo de servidor responsivo e altamente escalonável e um programa cliente responsivo. O livro contém duas versões: uma para iOS (iPad), criada usando o Xamarin Visual Studio, e a segunda, criada usando o Windows Presentation Foundation (WPF). Para garantir a escalabilidade máxima no aplicativo para servidor, é usada uma combinação de vários modelos de programação, como assíncrono, agente e reativo.

O livro também contém três aplicativos.

  • O Apêndice A descreve brevemente os conceitos básicos de programação funcional, além de apresentar a teoria básica dos métodos funcionais utilizados neste livro.
  • O Apêndice B revela os conceitos básicos da linguagem F #. Esta é uma revisão básica do F #, que permitirá que você se familiarize com esse idioma e se sinta à vontade ao ler um livro.
  • O Apêndice B demonstra vários métodos que simplificam a interação entre um fluxo de trabalho assíncrono em F # e uma tarefa .NET em C #.

Trecho. 11.6 Processador: 10.000 agentes para o Jogo da Vida


Comparado aos threads, o MailboxProcessor em combinação com fluxos de trabalho assíncronos é uma unidade de computação simples (primitiva). Os agentes podem aparecer e ser destruídos a um custo mínimo. Você pode distribuir o trabalho entre vários objetos MailboxProcessor da mesma maneira que você pode usar threads, sem a sobrecarga adicional associada à criação de um novo thread. Graças a isso, é bem possível criar aplicativos que consistem em centenas de milhares de agentes trabalhando em paralelo com uma carga mínima nos recursos do computador.

Nesta seção, usaremos várias instâncias do MailboxProcessor para implementar o jogo Game of Life (o jogo "Life") ( wiki-eng e wiki-rus ). Segundo a Wikipedia, o Jogo da Vida, em palavras simples, é um autômato celular. Este é um jogo sem jogadores - em outras palavras, quando um jogo começa com uma configuração inicial aleatória, ele é executado sem nenhuma outra entrada. O jogo consiste em um conjunto de células formando uma grade; em cada célula são cumpridas várias regras matemáticas. As células podem viver, morrer e se multiplicar. Cada célula interage com oito vizinhos (células vizinhas). Para mover as células de acordo com essas regras, é necessário calcular constantemente o novo estado da grade.

Game of Life tem as seguintes regras:

  • se uma célula tem apenas um vizinho ou nenhum vizinho, morre "por solidão";
  • se quatro ou mais vizinhos de uma célula morrem, ela morre "devido à superpopulação";
  • se a célula tiver dois ou três vizinhos, resta viver;
  • se uma célula tem três vizinhos, ela se multiplica.

Dependendo das condições iniciais, as células formam estruturas características ao longo do jogo. Através da aplicação repetida das regras, as seguintes gerações de células são criadas até que as células atinjam um estado estável (Fig. 11.12).

A Listagem 11.9 mostra a implementação da célula Agent of Cell do Game of Life, com base nos tipos de F # do MailboxProcessor. Cada célula do agente interage com as células vizinhas por meio de mensagens assíncronas, criando assim um Jogo da Vida totalmente paralelo. Por uma questão de brevidade, omiti algumas partes do código, pois elas não estão relacionadas ao tópico principal do exemplo. Você encontrará a implementação completa no código-fonte deste livro, publicado no site do editor.

imagem

imagem

O AgentCell descreve uma célula na grade do Jogo da Vida. O conceito básico é que cada agente troque informações com células vizinhas sobre seu estado atual por meio de mensagens assíncronas. Este modelo cria uma cadeia de comunicações paralelas interconectadas que envolve todas as células que enviam seus estados atualizados para o MailApProcessor updateAgent. Após receber esses dados, o updateAgent atualiza os gráficos na interface do usuário (Listagem 11.10).

imagem

imagem

updateAgent, como o nome indica, atualiza o estado de cada pixel de acordo com o valor da célula recebido na mensagem Atualizar. O agente mantém o estado dos pixels e o usa para criar uma nova imagem quando todas as células transmitem seu novo estado. O UpdateAgent atualiza a GUI do WPF usando esta nova imagem que corresponde à grade atual do Jogo da Vida:

do! Async.SwitchToContext ctx image.Source <- createImage pixels do! Async.SwitchToThreadPool() 

É importante observar que o updateAgent usa o contexto de sincronização atual para atualizar corretamente o controlador WPF. O thread atual é alternado para o thread da interface do usuário usando a função Async.SwitchToContext (descrita no Capítulo 9).

O último trecho de código para executar o Game of Life gera uma grade que serve como um playground para as células e, em seguida, o timer notifica as células sobre a necessidade de executar uma atualização (Listagem 11.11). Neste exemplo, a grade é um quadrado de 100 × 100 células, um total de 10.000 células (objetos MailboxProcessor), calculadas em paralelo com um timer a cada 50 ms, como mostra a Fig. 11.13 Dez mil objetos MailboxProcessor interagem e atualizam a interface do usuário 20 vezes por segundo (o código no qual você deve prestar atenção é mostrado em negrito).

imagem

imagem

As notificações para todas as células (agentes) são enviadas em paralelo usando o PLINQ. As células são seqüências de F # que são tratadas como .NET IEnumerable, facilitando a integração do LINQ / PLINQ.

imagem

Quando o código é executado, o programa gera 10.000 objetos F # do tipo MailboxProcessor em menos de 1 ms, enquanto os agentes ocupam menos de 25 MB de memória. Impressionante!

Sumário


  • O modelo de programação baseado em agentes naturalmente fornece imutabilidade e isolamento ao escrever sistemas competitivos, facilitando ainda mais a discussão de sistemas complexos, pois os agentes são encapsulados em objetos ativos.
  • Um manifesto reativo define as propriedades para implementar um sistema reativo que seja flexível, com pouco acoplamento e escalonável.
  • O isolamento natural é importante para escrever código competitivo sem bloquear. Em um programa multithread, o isolamento resolve o problema de estados compartilhados, fornecendo a cada thread uma parte copiada dos dados para executar cálculos locais. Ao usar isolamento, não há condição de corrida.
  • Por serem assíncronos, os agentes são simples porque não bloqueiam threads enquanto aguardam mensagens. Como resultado, você pode usar centenas de milhares de agentes em um aplicativo sem muito impacto no tamanho da memória.
  • Um objeto MailboxProcessor F # fornece comunicação bidirecional: um agente pode usar um canal assíncrono para retornar (responder) o resultado do cálculo ao objeto de chamada.
  • O modelo de programação do agente no F # através do MailboxProcessor é uma excelente ferramenta para solucionar gargalos em aplicativos, como acesso simultâneo a vários bancos de dados. De fato, com a ajuda de agentes, você pode acelerar significativamente o trabalho dos aplicativos, mantendo a capacidade de resposta do servidor.
  • Outras linguagens de programação .NET permitem que você use o MailboxProcessor do tipo F #, fornecendo métodos usando o conveniente modelo de programação TPL com base em tarefas.

»Mais informações sobre o livro podem ser encontradas no site do editor
» Conteúdo
» Trecho

Cupom de 20% de desconto para vendedores ambulantes - Simultaneidade no .NET

Após o pagamento da versão em papel do livro, uma versão eletrônica do livro é enviada por e-mail.

Source: https://habr.com/ru/post/pt453804/


All Articles