Aprendendo programação assíncrona [fechado]

21

A programação assíncrona, sem bloqueio de eventos, parece ser a última moda. Eu tenho uma compreensão conceitual básica do que tudo isso significa. No entanto, o que não tenho certeza é quando e onde meu código pode se beneficiar de ser assíncrono ou de como fazer o bloqueio de E / S não-bloqueio. Tenho certeza de que posso simplesmente usar uma biblioteca para fazer isso, mas estou mais interessado em conceitos mais detalhados e nas várias maneiras de implementá-lo.

Existem livros abrangentes / definitivos ou outros recursos sobre esse assunto (como GoF for Design Patterns ou K&R for C, tldp para coisas como bash)?

(Observação: não tenho certeza se essa é realmente uma pergunta funcionalmente idêntica à minha pergunta sobre programação orientada a eventos de aprendizagem )

xenoterracida
fonte
Comece com a base mais fundamental: en.wikipedia.org/wiki/Pi-calculus
SK-logic

Respostas:

35

A programação assíncrona é muito mais uma filosofia do que apenas outro truque de programação. Embora sua última pergunta tenha atraído respostas principalmente sobre aspectos de programação e minha resposta foi um solitário desconectado por ser principalmente teórico, estou tentando fornecer uma nova perspectiva construindo na mesma linha, mas explicações, e não apenas referências.

Este é sobre alguns fundamentos do porquê e como da Programação Assíncrona.

Vamos supor que você vá a uma padaria (e suponha que o bolo seja preparado após o pedido) - você tem duas opções: optar por esperar até o bolo ficar pronto ou dar o pedido e voltar para casa e pegar depois quando estiver pronto. O primeiro (espera) é um método síncrono e, posteriormente, é um método assíncrono . Escusado será dizer que este exemplo fornece uma boa referência por que você deve usar métodos assíncronos sobre síncrona.

A programação baseada em eventos é apenas uma das maneiras pelas quais os sistemas assíncronos podem ser construídos e não é apenas um padrão de design útil, mas um padrão de arquitetura. Estou listando casos em que essa teoria é usada de uma maneira praticamente útil - esperando que isso traga alguma clareza

  1. Um dos primeiros exemplos de sistemas assíncronos é o sistema Unix IO. Enquanto nós sabemos read(), write()e até mesmo select()chama blocos o fluxo do programa, mas dentro do OS, eles são assíncronas, isto é, o kernel geralmente sabe que o dispositivo de bloco (aka disco rígido) vai levar algum tempo para tampão de enchimento, até que tais CPU vez que um é livre desse segmento respectivo e, portanto, o segmento está estacionado como (não está pronto). Consulte 1. Moris Bach "O design do sistema operacional Unix"

  2. Outro exemplo mais comum é a maioria das estruturas de interface do usuário. Aqui, todos os cliques do usuário são despachados primeiro através de um controlador que, por sua vez, chama de volta o respectivo aplicativo. O importante é que esses retornos de chamada não devem manter os retornos em espera, caso contrário o sistema congelará. A chamada de retorno do controlador da interface do usuário para os back-ends geralmente é assíncrona se envolverem processamento pesado.

  3. Outro bom exemplo de programação assíncrona (como um padrão de design puro) é o Active Object. Um objeto ativo é aquele que possui seu próprio encadeamento privado, de modo que é possível manter muitos pedidos em uma fila e executar um por um. Consulte este documento: Objeto ativo . Esse padrão é muito usado desde o software Enterprise até as estruturas móveis. As plataformas populares Java / EJB e .NET permitem a chamada de método assíncrono local ou remoto , que essencialmente permite que objetos normais se tornem objetos ativos. Objetos ativos estavam presentes no Symbian: Objetos ativos no Symbian OS por Aapo Haapanen (veja também: Objetos ativos no Symbian ). Agora também está presente emAndroid ).

  4. Além do objeto Ativo, o mesmo autor Douglas C. Schmidt , produziu vários outros trabalhos que são outros paralelos ao objeto Ativo e também são os padrões assíncronos. Consulte este Event Handling Patterns e uma conta completa está disponível em seu livro Arquitetura de software orientada a padrões: padrões para objetos simultâneos e em rede - V2

  5. Quando um determinado objeto precisa retornar a API, enquanto trabalha em segundo plano para realmente realizar o trabalho, a metodologia usual é ter um sistema multithread para conseguir isso. Os sistemas encadeados estão presentes em todos os lugares, desde C (posix), C ++ ( boost ) a Java, C # e assim por diante. Objeto ativo é essencialmente apenas uma abstração que pode ocultar isso. Veja por que as implementações de objetos ativos são preferíveis a threads simples. Outra boa leitura .

  6. Mas esse conceito vai além de threads ou objetos dentro de um aplicativo para se tornar assíncrono. Um dos melhores usos é nos sistemas distribuídos, em que dois aplicativos não precisam necessariamente esperar um pelo outro pelas coordenações. O bom e velho RPC (ou não tão bom, da maneira que você vê) era síncrono. [é claro, também existem outros RPCs assíncronos ]. Mas as alternativas modernas, como o Message Oriented Middleware, são verdadeiramente assíncronas por boas razões.

  7. Por último, mas pode ser o mais interessante, é a programação de agentes, que pode se beneficiar do modelo de comunicação assíncrona .


Embora a programação assíncrona pareça sexy, ela cria sua própria complexidade, incluindo:

  • estrutura para passagem de valor de retorno
  • sobrecarga adicional de comunicação
  • necessidade adicional de construções de sincronização
  • possibilidade de impasses, corridas etc. se as coisas não forem bem feitas.

... e assim por diante.

Deve sempre ser usado apenas por razões genuínas.

Então, quando alguém deve usar o modelo assíncrono? Quando você deve colocar um encadeamento em segundo plano e permitir que o chamador assine síncrono? Aqui estão algumas boas regras quando aplicável (mas não completo)

  1. Quando o sistema deseja aplicar uma conversa estrita e séria sobre recursos: por exemplo, você deseja manter um número fixo absoluto de threads. O padrão assíncrono força o sistema a implementar a fila.

  2. Quando o interlocutor precisa fazer "outras coisas úteis a fazer" é realmente genuíno. Muitas vezes, o outro encadeamento, mesmo que seja desbloqueado, não fará nada de útil e fica pendurado na pesquisa de resultados. Isso realmente pode consumir mais CPU do que o modelo síncrono básico.

  3. Quando você precisar de níveis mais altos de confiabilidade em sistemas distribuídos. (consulte Middleware orientado a mensagens ).

Dipan Mehta
fonte
O link POSA está morto - web.archive.org/web/20170724063431/https://www.cse.wustl.edu/… ainda funciona
Élektra 03/01