À quoi sert le mot-clé async ?

En Python, le code s'exécute de manière synchrone : c'est-à-dire que chaque ligne de code doit attendre que la précédente soit terminée pour s'exécuter. Si une tâche prend du temps, alors il faudra attendre qu'elle se termine pour passer à la suite du programme.

Heureusement, il est possible d'utiliser les mots-clés async et await. Au lieu de bloquer l'exécution, Python peut mettre en pause une tâche pour avancer sur une autre.

Qu'est-ce que le GIL ?

Pour une explication complète sur le GIL, n'hésitez pas à aller voir notre glossaire sur le sujet.

Le GIL (Global Interpreter Lock) contraint Python à n'exécuter qu'une instruction à la fois dans le thread. Prenons un exemple :

import time


def tache_longue(nom):
    print(f"Début tâche {nom}")
    # Simulons une tâche longue avec sleep
    time.sleep(1)
    print(f"Fin tâche {nom}")

debut = time.time()
tache_longue("A") # Attend 1 seconde
tache_longue("B") # Attend encore 1 seconde
print(f"Temps total : {time.time() - debut}s")
# Résultat : Temps total : Environ 2 secondes
PYTHON

Il faut attendre 2 secondes pour que le programme se termine. Ce qui est inefficace pour des opérations d'E/S (I/O), comme les attentes lors d'appels réseau.

asyncio, async et await : la solution

La programmation asynchrone permet d'optimiser l'exécution d'un thread unique. Python pourra lancer une tâche et, pendant qu'elle attend, en lancer une autre.

Pour définir une fonction asynchrone (on parlera de coroutine), on utilise async def. Et pour utiliser un résultat sans bloquer, on utilise le mot-clé await.

Reprenons l'exemple précédent :

import time
import asyncio


async def tache_longue(nom):
    print(f"Début tâche {nom}")
    # Utilisation de asyncio.sleep pour ne pas bloquer l'événement
    await asyncio.sleep(1)
    print(f"Fin tâche {nom}")


async def main():
    debut = time.time()
    await asyncio.gather(
        tache_longue("A"),  # Attend 1 seconde
        tache_longue("B")   # Attend encore 1 seconde
    )
    print(f"Temps total : {time.time() - debut}s")


asyncio.run(main())
# Temps total : Environ 1 seconde
PYTHON

Pas mal de changements ici, décortiquons le code :

  • async def permet de transformer la fonction en coroutine

  • await asyncio.sleep(1) sert à simuler une opération comme l'attente de la réponse d'un serveur

  • asyncio.gather permet de lancer plusieurs tâches en même temps

  • asyncio.run(main()) démarre l'exécution asynchrone

Le temps d'exécution est divisé par deux. Pendant qu'une tâche est en pause, Python en profite pour avancer sur une autre.

Quand utiliser l'asynchrone avec Python ?

Attention, l'asynchrone n'est pas toujours la bonne approche. Pour les opérations I/O Bound comme les requêtes HTTP, l'accès à la base de données ou la lecture de fichiers, asyncio est tout à fait adapté.

Cependant, vous pouvez vous retrouver dans le cas où les lenteurs potentielles sont liées au processeur ; on parlera de CPU Bound. C'est le cas, par exemple, si vous effectuez des calculs lourds, du traitement d'images, etc.

Pourquoi ne pas prendre le temps d'aller lire notre glossaire sur multiprocessing ? 📚

Quelle est la différence entre async et threading en Python ?

Bien que les modules asyncio et threading servent tous les deux à faire de la concurrence, leur fonctionnement est différent :

  • asyncio utilise un seul thread et bascule entre les tâches. C'est très efficace au niveau de la gestion de la mémoire

  • threading crée plusieurs threads, ce qui est plus gourmand en mémoire

Pourquoi utiliser threading alors ?

De nombreuses bibliothèques Python ne sont pas compatibles avec asyncio (comme requests, par exemple). Dans ce cas précis, on préférera utiliser le multithreading avec threading. Nous avons un glossaire dédié au threading sur Docstring.

On pourrait aussi évoquer run_in_executor de asyncio, qui permet de lancer du code synchrone tout en utilisant des bibliothèques non asynchrones.

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.