Programação Orientada a Eventos
A programação orientada a eventos concentra-se em eventos. Eventualmente, o fluxo do programa depende de eventos. Até agora, estávamos lidando com um modelo de execução sequencial ou paralelo, mas o modelo com o conceito de programação orientada a eventos é chamado de modelo assíncrono. A programação orientada a eventos depende de um loop de eventos que está sempre ouvindo os novos eventos de entrada. O funcionamento da programação orientada a eventos depende de eventos. Depois que um evento é executado em loop, os eventos decidem o que executar e em que ordem. O fluxograma a seguir ajudará você a entender como isso funciona -
Módulo Python - Asyncio
O módulo Asyncio foi adicionado ao Python 3.4 e fornece infraestrutura para escrever código simultâneo de thread único usando co-rotinas. A seguir estão os diferentes conceitos usados pelo módulo Asyncio -
O loop de eventos
O loop de eventos é uma funcionalidade para manipular todos os eventos em um código computacional. Ele atua durante a execução de todo o programa e acompanha a entrada e a execução de eventos. O módulo Asyncio permite um único loop de evento por processo. A seguir estão alguns métodos fornecidos pelo módulo Asyncio para gerenciar um loop de eventos -
loop = get_event_loop() - Este método fornecerá o loop de eventos para o contexto atual.
loop.call_later(time_delay,callback,argument) - Este método organiza o retorno de chamada que deve ser chamado após os segundos de time_delay fornecidos.
loop.call_soon(callback,argument)- Este método organiza um retorno de chamada que deve ser chamado assim que possível. O retorno de chamada é chamado após call_soon () retornar e quando o controle retornar ao loop de eventos.
loop.time() - Este método é usado para retornar a hora atual de acordo com o relógio interno do loop de eventos.
asyncio.set_event_loop() - Este método definirá o loop de eventos do contexto atual para o loop.
asyncio.new_event_loop() - Este método irá criar e retornar um novo objeto de loop de evento.
loop.run_forever() - Este método será executado até que o método stop () seja chamado.
Exemplo
O seguinte exemplo de loop de evento ajuda na impressão hello worldusando o método get_event_loop (). Este exemplo foi retirado da documentação oficial do Python.
import asyncio
def hello_world(loop):
print('Hello World')
loop.stop()
loop = asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
loop.close()
Resultado
Hello World
Futuros
Isso é compatível com a classe concurrent.futures.Future que representa um cálculo que não foi realizado. Existem as seguintes diferenças entre asyncio.futures.Future e concurrent.futures.Future -
Os métodos result () e exception () não usam um argumento de tempo limite e geram uma exceção quando o futuro ainda não está pronto.
Callbacks registrados com add_done_callback () são sempre chamados via call_soon () do loop de evento.
A classe asyncio.futures.Future não é compatível com as funções wait () e as_completed () no pacote concurrent.futures.
Exemplo
A seguir está um exemplo que ajudará você a entender como usar a classe asyncio.futures.future.
import asyncio
async def Myoperation(future):
await asyncio.sleep(2)
future.set_result('Future Completed')
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
loop.run_until_complete(future)
print(future.result())
finally:
loop.close()
Resultado
Future Completed
Corrotinas
O conceito de co-rotinas no Asyncio é semelhante ao conceito de objeto Thread padrão no módulo de threading. Esta é a generalização do conceito de sub-rotina. Uma co-rotina pode ser suspensa durante a execução para que aguarde o processamento externo e retorne do ponto em que parou quando o processamento externo foi concluído. As duas maneiras a seguir nos ajudam na implementação de corrotinas -
função def assíncrona ()
Este é um método para implementação de co-rotinas no módulo Asyncio. A seguir está um script Python para o mesmo -
import asyncio
async def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Resultado
First Coroutine
decorador @ asyncio.coroutine
Outro método para implementação de co-rotinas é utilizar geradores com o decorador @ asyncio.coroutine. A seguir está um script Python para o mesmo -
import asyncio
@asyncio.coroutine
def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
Resultado
First Coroutine
Tarefas
Esta subclasse do módulo Asyncio é responsável pela execução de co-rotinas em um loop de eventos de maneira paralela. Seguir o script Python é um exemplo de processamento de algumas tarefas em paralelo.
import asyncio
import time
async def Task_ex(n):
time.sleep(1)
print("Processing {}".format(n))
async def Generator_task():
for i in range(10):
asyncio.ensure_future(Task_ex(i))
int("Tasks Completed")
asyncio.sleep(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()
Resultado
Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9
Transportes
O módulo Asyncio fornece classes de transporte para a implementação de vários tipos de comunicação. Essas classes não são thread-safe e sempre emparelhadas com uma instância de protocolo após o estabelecimento do canal de comunicação.
A seguir estão os diferentes tipos de transportes herdados do BaseTransport -
ReadTransport - Esta é uma interface para transportes somente leitura.
WriteTransport - Esta é uma interface para transportes somente gravação.
DatagramTransport - Esta é uma interface para envio de dados.
BaseSubprocessTransport - Semelhante à classe BaseTransport.
A seguir estão cinco métodos distintos da classe BaseTransport que são subsequentemente transitórios entre os quatro tipos de transporte -
close() - Fecha o transporte.
is_closing() - Este método retornará verdadeiro se o transporte estiver fechando ou já estiver fechado.transports.
get_extra_info(name, default = none) - Isso nos dará algumas informações extras sobre o transporte.
get_protocol() - Este método retornará o protocolo atual.
Protocolos
O módulo Asyncio fornece classes básicas que você pode criar em subclasses para implementar seus protocolos de rede. Essas classes são usadas em conjunto com transportes; o protocolo analisa os dados de entrada e pede a gravação dos dados de saída, enquanto o transporte é responsável pela E / S e pelo armazenamento em buffer. A seguir estão três classes de protocolo -
Protocol - Esta é a classe base para implementar protocolos de streaming para uso com transportes TCP e SSL.
DatagramProtocol - Esta é a classe base para implementar protocolos de datagrama para uso com transportes UDP.
SubprocessProtocol - Esta é a classe base para implementar protocolos que se comunicam com processos filhos por meio de um conjunto de tubos unidirecionais.