6.1 Obtendo o loop de eventos
O loop de eventos (Event Loop) é um componente central na programação assíncrona usando o módulo asyncio em Python. Ele gerencia a execução de tarefas assíncronas, processamento de eventos e execução de operações de entrada/saída. O loop de eventos permite que várias tarefas sejam executadas simultaneamente, sem bloquear o fluxo principal de execução.
Criando e obtendo o loop de eventos
-
asyncio.get_event_loop(): Retorna o loop de eventos atual ou cria um novo, se não houver um atual. -
asyncio.new_event_loop(): Cria um novo loop de eventos. -
asyncio.set_event_loop(loop): Define o loop de eventos especificado como o atual.
Exemplo:
O asyncio tem um loop de eventos atual, que contém todas as tarefas a serem executadas. Você pode obter o loop de eventos atual ou criar um novo e configurá-lo como o atual. Isso é feito no exemplo abaixo.
import asyncio
loop = asyncio.get_event_loop()
print(loop) # Loop de eventos atual
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # Novo loop de eventos definido
Vale a pena notar que o método get_event_loop() retorna o loop de eventos ativo atual. A criação de um novo loop de eventos e sua definição devem ser usadas com cuidado para evitar conflitos em aplicativos assíncronos.
Executando o loop de eventos
-
run_forever(): Executa o loop de eventos e continua sua execução até questop()seja chamado. -
run_until_complete(future): Executa o loop de eventos e termina depois que a coroutine ou objeto futuro especificado é concluído.
Exemplo:
O loop de eventos pode ser iniciado de duas maneiras: trabalhar indefinidamente — como um while True, ou até que uma tarefa específica seja concluída.
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1)
print("World")
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
Se você executou o Event Loop no modo run_forever(), ele ficará girando indefinidamente. O método run_forever() só terminará se alguma tarefa assíncrona chamar o método stop() do nosso EventLoop.
Parando o loop de eventos
stop(): Para o loop de eventos.-
is_running(): RetornaTrue, se o loop de eventos está em execução.
Exemplo:
Se o loop foi iniciado no modo infinito, ele recebe tarefas e as executa continuamente, não parando sozinho. Alguém deve obter o objeto do nosso loop atual e chamar o método stop() nele. Para saber se o loop eterno está girando ou não, você precisa chamar o método is_running().
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 Métodos importantes do loop de eventos
Método call_soon(callback, *args)
Agenda a chamada da função callback com argumentos *args o mais rápido possível.
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
Coloca a função callback no início da lista de tarefas, para que ela comece a ser executada o mais rápido possível. Você pode passar funções não assíncronas para o método. Este método é útil quando você precisa executar uma tarefa com o menor atraso possível, especialmente quando é necessário um retorno rápido em um aplicativo assíncrono.
Método call_later(delay, callback, *args)
Agenda a chamada da função callback com argumentos *args após delay segundos.
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
Este método permite executar uma chamada de função atrasada: o primeiro parâmetro é o atraso em segundos (pode ser fracionário), e em seguida, a referência da função e seus parâmetros. Você pode passar funções não assíncronas para o método. Este método pode ser usado para gerenciar a execução de tarefas com diferentes graus de urgência, o que é útil ao projetar sistemas assíncronos complexos.
Método call_at(when, callback, *args)
Agenda a chamada da função callback com argumentos *args no momento when.
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # Em 2 segundos a partir do tempo atual do loop de eventos
loop.call_at(when, my_callback)
loop.run_forever()
Se você quiser executar uma tarefa não em 5 segundos, mas, por exemplo, às 15:00 ou 24:00, será mais conveniente usar a função call_at(), que funciona como a função call_soon(), mas o primeiro parâmetro é o momento em que a função especificada deve ser chamada. Você pode passar funções não assíncronas para o método.
Vantagens e características
Execução assíncrona: O loop de eventos permite executar várias tarefas em paralelo, sem bloquear o fluxo principal de execução.
Gerenciamento eficiente de recursos: Operações de entrada/saída assíncronas são realizadas sem bloqueio, tornando os programas mais eficientes.
Flexibilidade e escalabilidade: O loop de eventos suporta vários métodos para agendamento de tarefas e processamento de eventos, permitindo a criação de aplicativos assíncronos complexos e escaláveis.
6.3 Interagindo com tarefas e futuros
O loop de eventos gerencia a execução de tarefas (Tasks) e objetos futuros (Futures). Ele monitora seu estado e garante sua execução à medida que ficam prontos.
Exemplo:
import asyncio
async def main():
await asyncio.sleep(1)
print("Task completed")
loop = asyncio.get_event_loop()
task = loop.create_task(main())
loop.run_until_complete(task)
Este exemplo mostra como o loop de eventos gerencia a execução de uma tarefa, criada com o método create_task. Os métodos call_soon(), call_later() e call_at() podem ser usados para gerenciar a execução de tarefas com diferentes graus de urgência, o que é útil ao projetar sistemas assíncronos complexos.
GO TO FULL VERSION