5.1 Event Loop
Agora vamos falar um pouquinho da segunda parte da assincronia, que parece estar em todos os lugares: o loop de eventos (Event Loop), as tarefas (Task) e o Future.
Imagine o Event Loop como o maestro de uma orquestra, Task como os músicos e Future como as partituras que os músicos devem tocar. O maestro (Event Loop) coordena o trabalho dos músicos (Task), que executam a música (operações assíncronas), lendo as partituras (Future).
O ciclo de eventos (Event Loop) é a base da programação assíncrona em Python. Ele é responsável por executar tarefas assíncronas, gerenciar eventos e tratar operações de entrada e saída. O ciclo de eventos verifica continuamente se há novos eventos ou tarefas e os executa quando estão prontos.
Funções principais
-
run_forever(): Inicia o ciclo de eventos e continua sua execução até questop()seja chamado. -
run_until_complete(future): Inicia o ciclo de eventos e o finaliza após a conclusão do objeto ou coroutine futuro especificado. stop(): Interrompe o ciclo de eventos.-
create_task(coroutine): Agenda a execução de uma coroutine como uma tarefa.
Exemplo de uso:
import asyncio
async def hello():
print("Hello, world!") # Olá, mundo!
await asyncio.sleep(1)
print("Hello again!") # Olá de novo!
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
Neste exemplo, primeiro usamos o método get_event_loop() para obter o objeto atual EventLoop da biblioteca asyncio.
Em seguida, adicionamos a coroutine hello a este EventLoop e pedimos para executá-la usando o método run_until_complete().
No último passo, fechamos o EventLoop com o método close().
Ao executar este código, você verá que primeiro será exibido "Hello, world!", o programa vai esperar 1 segundo, e depois será exibido "Hello again!". Isso demonstra como o Event Loop gerencia a execução de uma função assíncrona.
Vamos examinar mais detalhadamente essas ações na próxima aula.
5.2 Tasks
Tarefas (Tasks) são uma espécie de invólucro para coroutines, permitindo gerenciar sua execução e rastrear seu estado. As tarefas permitem executar coroutines em paralelo, controlando-as através do ciclo de eventos.
Criação e gerenciamento de tarefas
-
asyncio.create_task(coroutine): Cria uma tarefa para executar uma coroutine. -
Task.result(): Retorna o resultado de uma tarefa concluída ou lança uma exceção se a tarefa terminou com erro. Task.cancel(): Cancela a execução de uma tarefa.
Exemplo de uso:
import asyncio
async def say_hello():
await asyncio.sleep(1)
print("Hello")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
Neste exemplo, envolvemos a coroutine say_hello() em um objeto Task. Ele também é um objeto assíncrono, por isso, para obter seu resultado, precisamos aplicar o operador await a ele.
Ao executar este código, o programa irá esperar 1 segundo e então exibir "Hello". Isso demonstra como Task gerencia a execução da coroutine e como podemos aguardar sua conclusão com o await.
Mais detalhes sobre o trabalho com tarefas Task serão discutidos na próxima aula.
5.3 Futures
Objetos Future representam o resultado de uma operação assíncrona que estará disponível no futuro. Eles permitem gerenciar o estado de uma operação assíncrona, definindo o resultado ou exceção.
Métodos principais:
-
set_result(result): Define o resultado para o objetoFuture. -
set_exception(exception): Define uma exceção para o objetoFuture. -
result(): Retorna o resultado do objetoFutureou lança uma exceção se a operação terminou com erro. -
exception(): Retorna a exceção, se ela foi definida.
Exemplo de uso:
import asyncio
async def set_future(fut, value):
await asyncio.sleep(1)
fut.set_result(value)
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
await set_future(fut, 'Hello, future!')
print(fut.result())
asyncio.run(main())
Neste exemplo, criamos um Future, definimos seu valor após um segundo e então exibimos o resultado. Você verá que o programa irá aguardar um segundo antes de exibir 'Hello, future!'. Isso demonstra como o Future representa um resultado que se tornará disponível no futuro.
Ao contrário do objeto Task, o objeto Future está vinculado a um Event Loop específico, e a função assíncrona executada pode escrever seu resultado nele. Embora geralmente isso funcione de forma um pouco diferente.
Na maioria das vezes, objetos Future são usados em conjunto com tarefas Task, que fornecem um controle mais avançado sobre as operações assíncronas.
Agora que você está mais familiarizado com Event Loop, Task e Future, vamos explorá-los com mais detalhes.
GO TO FULL VERSION