6.1 Obtenir une boucle d'événements
La boucle d'événements (Event Loop)
est le composant central de la programmation asynchrone avec le module asyncio en Python. Elle gère l'exécution des tâches asynchrones, le traitement des événements et l'exécution des opérations d'entrée-sortie. La boucle d'événements permet à plusieurs tâches de s'exécuter simultanément sans bloquer le fil d'exécution principal.
Création et obtention d'une boucle d'événements
-
asyncio.get_event_loop()
: Retourne la boucle d'événements actuelle ou en crée une nouvelle si elle n'existe pas. -
asyncio.new_event_loop()
: Crée une nouvelle boucle d'événements. -
asyncio.set_event_loop(loop)
: Définit la boucle d'événements spécifiée comme étant la boucle actuelle.
Exemple :
asyncio a une boucle d'événements actuelle qui contient toutes les tâches en cours. Vous pouvez obtenir la boucle d'événements actuelle ou en créer une nouvelle et la définir comme actuelle. C'est ce qui se passe dans l'exemple ci-dessous.
import asyncio
loop = asyncio.get_event_loop()
print(loop) # Boucle d'événements actuelle
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
print(asyncio.get_event_loop()) # Nouvelle boucle d'événements définie
Il est à noter que la méthode get_event_loop()
retourne la boucle d'événements active actuelle. La création d'une nouvelle boucle et sa définition doivent être utilisées avec précaution pour éviter les conflits dans les applications asynchrones.
Exécution de la boucle d'événements
-
run_forever()
: Démarre la boucle d'événements et continue son exécution jusqu'à ce questop()
soit appelé. -
run_until_complete(future)
: Démarre la boucle d'événements et la termine après la réalisation de la coroutine donnée ou de l'objet future.
Exemple :
La boucle d'événements peut être démarrée en deux modes : fonctionner indéfiniment — quelque chose comme while True
, ou jusqu'à l'exécution d'une tâche spécifique.
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()
Si vous avez démarré Event Loop
en mode run_forever()
, elle bouclera indéfiniment. La méthode run_forever()
s'arrêtera uniquement si une tâche asynchrone appelle la méthode stop()
sur notre EventLoop
.
Arrêt de la boucle d'événements
stop()
: Arrête la boucle d'événements.-
is_running()
: RetourneTrue
si la boucle d'événements est en cours d'exécution.
Exemple :
Si la boucle est démarrée en mode infini, elle reçoit constamment des tâches et les exécute, elle ne s'arrêtera pas d'elle-même. Quelqu'un doit obtenir l'objet de notre boucle actuelle et appeler sa méthode stop()
. Pour savoir si la boucle tourne éternellement ou non, il faut appeler la méthode is_running()
.
import asyncio
loop = asyncio.get_event_loop()
loop.stop()
print(loop.is_running()) # False
6.2 Méthodes importantes de la boucle d'événements
Méthode call_soon(callback, *args)
Planifie l'appel de la fonction callback
avec les arguments *args
dès que possible.
import asyncio
def my_callback():
print("Callback executed")
loop = asyncio.get_event_loop()
loop.call_soon(my_callback)
loop.run_forever()
Place la fonction callback
au tout début de la liste des tâches pour qu'elle commence à s'exécuter aussi vite que possible. On peut transmettre des fonctions non-asynchrones à cette méthode. Elle est utile lorsque vous avez besoin d'exécuter une tâche avec un minimum de délais, surtout quand une réponse immédiate est nécessaire dans une application asynchrone.
Méthode call_later(delay, callback, *args)
Planifie l'appel de la fonction callback
avec les arguments *args
après delay
secondes.
import asyncio
def my_callback():
print("Callback executed after delay")
loop = asyncio.get_event_loop()
loop.call_later(2, my_callback)
loop.run_forever()
Cette méthode permet d'effectuer un appel de fonction différé : le premier paramètre est le délai en secondes (peut être fractionnaire), suivi de la référence à la fonction et de ses paramètres. On peut transmettre des fonctions non-asynchrones. Cette méthode est utile pour gérer l'exécution des tâches avec des degrés d'urgence différents, ce qui est pratique dans la conception de systèmes asynchrones complexes.
Méthode call_at(when, callback, *args)
Planifie l'appel de la fonction callback
avec les arguments *args
à l'instant when
.
import asyncio
import time
def my_callback():
print("Callback executed at specific time")
loop = asyncio.get_event_loop()
when = loop.time() + 2 # Dans 2 secondes à partir du temps courant de la boucle d'événements
loop.call_at(when, my_callback)
loop.run_forever()
Si vous souhaitez lancer une tâche non pas dans 5 secondes, mais par exemple à 15h00 ou 24h00, vous trouverez plus pratique d'utiliser la fonction call_at()
, qui fonctionne de la même manière que la fonction call_soon()
, mais le premier paramètre est l'heure à laquelle la fonction doit être appelée. On peut transmettre des fonctions non-asynchrones.
Avantages et caractéristiques
Exécution asynchrone: La boucle d'événements permet d'exécuter plusieurs tâches en parallèle sans bloquer le fil d'exécution principal.
Gestion efficace des ressources: Les opérations d'entrée-sortie asynchrones sont effectuées sans blocage, rendant les programmes plus efficaces.
Flexibilité et évolutivité: La boucle d'événements prend en charge de nombreuses méthodes pour planifier des tâches et gérer des événements, permettant ainsi de créer des applications asynchrones complexes et évolutives.
6.3 Interaction avec les tâches et les objets futurs
La boucle d'événements gère l'exécution des tâches (Tasks) et des objets futurs (Futures). Elle suit leur état et assure leur exécution dès qu'ils sont prêts.
Exemple :
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)
Cet exemple montre comment la boucle d'événements gère l'exécution d'une tâche créée avec la méthode create_task
. Les méthodes call_soon()
, call_later()
et call_at()
peuvent être utilisées pour gérer l'exécution des tâches avec des degrés d'urgence différents, ce qui est utile dans la conception de systèmes asynchrones complexes.
GO TO FULL VERSION