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 objetoFuture
ou 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