Qu'est-ce que la programmation asynchrone et pourquoi l'utiliser
La programmation asynchrone permet d'exécuter plusieurs opérations simultanément sans attendre la fin de chacune d'elles. C'est essentiel pour créer des applications performantes qui ne se bloquent pas lors d'opérations lentes.
Les principaux avantages de l'asynchrone
L'asynchrone est particulièrement efficace dans les scénarios suivants :
- Requêtes réseau (requêtes HTTP, travail avec des API REST)
- Opérations sur le système de fichiers (lecture et écriture de fichiers volumineux)
- Interaction avec les bases de données (requêtes SQL, opérations NoSQL)
- Connexions WebSocket et applications en temps réel
- Parsing de pages web et scraping de données
- Traitement de files d'attente de messages
Introduction à la bibliothèque asyncio
asyncio est la bibliothèque standard de Python pour écrire du code asynchrone basé sur une boucle d'événements (event loop). Elle fait partie de Python depuis la version 3.4 et a été considérablement améliorée dans les versions 3.7+.
Fonctionnalités clés d'asyncio
Avec asyncio, vous pouvez :
- Créer et gérer des coroutines
- Lancer plusieurs tâches asynchrones en parallèle
- Gérer efficacement des milliers de connexions simultanées
- Vous intégrer avec des bibliothèques et frameworks asynchrones
Concepts fondamentaux d'asyncio
Les coroutines
Une coroutine est une fonction spéciale qui peut être suspendue puis reprise. En Python, les coroutines sont définies avec le mot-clé async def.
import asyncio
async def saluer():
print("Bonjour !")
await asyncio.sleep(1)
print("1 seconde s'est écoulée.")
# Lancement de la coroutine
asyncio.run(saluer())
Le mot-clé await
await est utilisé pour suspendre l'exécution d'une coroutine jusqu'à la fin d'une autre opération asynchrone. C'est le mécanisme clé pour redonner le contrôle à la boucle d'événements.
async def message_differe():
print("Début de l'exécution")
await asyncio.sleep(2)
print("Message après 2 secondes")
asyncio.run(message_differe())
La boucle d'événements (Event Loop)
L'Event Loop est le cœur d'asyncio, le mécanisme qui gère l'exécution de toutes les tâches asynchrones. Depuis Python 3.7, il est recommandé d'utiliser asyncio.run() pour lancer du code asynchrone.
# Méthode moderne (Python 3.7+)
asyncio.run(coroutine_principale())
# Méthode ancienne (avant Python 3.7)
boucle = asyncio.get_event_loop()
boucle.run_until_complete(coroutine_principale())
Création et gestion des tâches asynchrones
Exécution parallèle des tâches
Le code asynchrone révèle toute sa puissance lors de l'exécution parallèle de plusieurs tâches :
async def tache(nom, delai):
print(f"Tâche {nom} démarrée")
await asyncio.sleep(delai)
print(f"Tâche {nom} terminée après {delai} secondes")
return f"Résultat de {nom}"
async def main():
# Méthode 1 : asyncio.gather()
resultats = await asyncio.gather(
tache("A", 2),
tache("B", 1),
tache("C", 3)
)
print("Tous les résultats :", resultats)
asyncio.run(main())
Création de tâches avec asyncio.create_task()
Pour un meilleur contrôle de l'exécution, utilisez asyncio.create_task() :
async def main():
# Création des tâches
tache_a = asyncio.create_task(tache("A", 2))
tache_b = asyncio.create_task(tache("B", 1))
tache_c = asyncio.create_task(tache("C", 3))
# Attente de leur achèvement
await tache_a
await tache_b
await tache_c
asyncio.run(main())