6.1 Ottenere il ciclo di eventi
Il ciclo di eventi (Event Loop)
è il componente centrale nella programmazione asincrona utilizzando il modulo asyncio in Python. Gestisce l'esecuzione delle attività asincrone, l'elaborazione degli eventi e l'esecuzione delle operazioni di input-output. Il ciclo di eventi permette a più attività di essere eseguite simultaneamente, senza bloccare il flusso principale di esecuzione.
Creare e ottenere il ciclo di eventi
-
asyncio.get_event_loop()
: Restituisce il ciclo di eventi corrente o ne crea uno nuovo, se quello corrente non esiste. -
asyncio.new_event_loop()
: Crea un nuovo ciclo di eventi. -
asyncio.set_event_loop(loop)
: Imposta il ciclo di eventi specificato come corrente.
Esempio:
asyncio ha un ciclo di eventi corrente che contiene tutte le attività in esecuzione. Puoi ottenere il ciclo di eventi corrente o crearne uno nuovo e impostarlo come corrente. Questo è ciò che accade nell'esempio sottostante.
import asyncio
loop = asyncio.get_event_loop()
print(loop) # Ciclo di eventi corrente
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # Nuovo ciclo di eventi impostato
È importante notare che il metodo get_event_loop()
restituisce il ciclo di eventi corrente attivo. La creazione di un nuovo ciclo di eventi e la sua impostazione devono essere effettuate con attenzione per evitare conflitti nelle applicazioni asincrone.
Eseguire il ciclo di eventi
-
run_forever()
: Avvia il ciclo di eventi e continua la sua esecuzione finché non viene chiamatostop()
. -
run_until_complete(future)
: Avvia il ciclo di eventi e lo termina dopo aver completato la coroutine o l'oggetto futuro specificato.
Esempio:
Il ciclo di eventi può essere avviato in due modalità: eseguire all'infinito - come un while True
, o finché non viene completato un compito specifico.
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 avvii l'Event Loop
in modalità run_forever()
, continuerà a eseguire il ciclo all'infinito. Il metodo run_forever()
cesserà di funzionare solo se un'attività asincrona chiama sul nostro EventLoop
il metodo stop()
.
Interrompere il ciclo di eventi
stop()
: Interrompe il ciclo di eventi.-
is_running()
: RestituisceTrue
se il ciclo di eventi è in esecuzione.
Esempio:
Se il ciclo è avviato in modalità infinita, continua a ricevere compiti e ad eseguirli, quindi di per sé non si fermerà. Qualcuno deve ottenere l'oggetto del nostro ciclo corrente e chiamare su di esso il metodo stop()
. Per sapere se il ciclo eterno è in esecuzione o meno, bisogna chiamare il metodo is_running()
.
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 Metodi importanti del ciclo di eventi
Metodo call_soon(callback, *args)
Pianifica la chiamata della funzione callback
con gli argomenti *args
il prima possibile.
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
Inserisce la funzione callback
all'inizio della lista dei compiti, così che inizi a essere eseguita il prima possibile. Si possono passare anche funzioni non asincrone a questo metodo. Questo metodo è utile quando è necessario eseguire un compito con il minimo ritardo, specialmente quando è richiesto un feedback immediato nell'applicazione asincrona.
Metodo call_later(delay, callback, *args)
Pianifica la chiamata della funzione callback
con gli argomenti *args
dopo delay
secondi.
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
Questo metodo permette di eseguire una chiamata ritardata a una funzione: il primo parametro è il ritardo in secondi (può essere frazionario) e successivamente il riferimento alla funzione e i suoi parametri. Si possono passare anche funzioni non asincrone a questo metodo. Questo metodo può essere utilizzato per gestire l'esecuzione di compiti con diversi gradi di urgenza, il che è utile nella progettazione di sistemi asincroni complessi.
Metodo call_at(when, callback, *args)
Pianifica la chiamata della funzione callback
con gli argomenti *args
al momento when
.
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # Dopo 2 secondi dall'orario corrente del ciclo di eventi
loop.call_at(when, my_callback)
loop.run_forever()
Se desideri avviare un compito non tra 5 secondi, ma ad esempio alle 15:00 o alle 24:00, ti sarà più comodo utilizzare la funzione call_at()
, che funziona come la funzione call_soon()
, ma il primo parametro che riceve non è la durata della pausa, ma l'ora in cui si desidera chiamare la funzione specificata. Si possono passare anche funzioni non asincrone a questo metodo.
Vantaggi e caratteristiche
Esecuzione asincrona: Il ciclo degli eventi permette di eseguire molte attività in parallelo, senza bloccare il flusso principale di esecuzione.
Gestione efficiente delle risorse: Le operazioni di input-output asincrone vengono eseguite senza bloccare, rendendo i programmi più efficienti.
Flessibilità e scalabilità: Il ciclo degli eventi supporta molti metodi per la pianificazione delle attività e l'elaborazione degli eventi, permettendo di creare applicazioni asincrone complesse e scalabili.
6.3 Interazione con compiti e oggetti futuri
Il ciclo degli eventi gestisce l'esecuzione delle attività (Tasks) e degli oggetti futuri (Futures). Tiene traccia del loro stato e ne assicura l'esecuzione man mano che sono pronti.
Esempio:
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)
In questo esempio viene mostrato come il ciclo degli eventi gestisce l'esecuzione di un compito creato utilizzando il metodo create_task
. I metodi call_soon()
, call_later()
e call_at()
possono essere usati per gestire l'esecuzione di compiti con diversi gradi di urgenza, il che è utile nella progettazione di sistemi asincroni complessi.
GO TO FULL VERSION