Programmation asynchrone dans Python

La programmation asynchrone dans Python vous permet d’écrire du code qui peut effectuer plusieurs autres tâches en attendant des opérations lentes. Il gère plusieurs tâches sans nécessiter la création de plusieurs threads.
La programmation asynchrone Python n’est pas la même chose que le multi-threading. Même s’ils atteignent tous les deux la concurrence, les tâches multi-threading s’exécutent en parallèle sur plusieurs threads, tandis que les fonctions de programmation asynchrones fonctionnent de manière asynchrone à l’aide de la boucle d’événement.
La programmation asynchrone est plus utile lorsque votre programme passe beaucoup de temps En attente d’entrée ou de sortie (E / S), comme:
- Grattage Web de nombreuses pages en même temps
- Faire plusieurs appels d’API immédiatement
- Lire ou écrire des fichiers volumineux
- Exécution des requêtes de base de données sur un réseau
Dans Python, la programmation asynchrone est implémentée à l’aide du bibliothèque Asyncio. Une implémentation de base est donnée ci-dessous.
import asyncio;
async def greet():
print("hello");
await asyncio.sleep(1);
print("world");
async def main():
await greet()
asyncio.run(main())
Le greet
La fonction est asynchrone; Il imprime «Hello» puis fait une pause pendant une seconde, avant finalement d’imprimer «monde».
La bibliothèque Asyncio englobe plusieurs concepts clés:
- Async – Pour définir une fonction asynchrone
- Await – utilisé à l’intérieur d’une fonction asynchrone pour suspendre l’exécution jusqu’à ce que la tâche attendue soit terminée
- Run – Exécute la coroutine principale et gère la boucle d’événement
- Coroutine – Une fonction spéciale définie avec l’async qui peut être interrompue et reprendre
- Boucle d’événement – Responsable des tâches et rappels asynchrones
Coroutines
UN coroutine est une fonction qui peut faire une pause et reprendre son exécution, permettant une programmation asynchrone. Vous définissez une coroutine en utilisant le async def
mot-clé et peut utiliser le await
Mot-clé pour faire une pause jusqu’à ce qu’une autre opération asynchrone se termine.
async def coroutine_function():
print("Coroutine function started.")
await asyncio.sleep(1)
print("Coroutine function finished.")
Un exemple complet d’une coroutine avec une programmation asynchrone est la suivante.
import asyncio
import aiohttp
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.text()
print(f"Fetched data from {url} :{data[:100]}...")
return data
async def main():
urls = [
"http://jsonplaceholder.typicode.com/posts/1",
"http://jsonplaceholder.typicode.com/posts/2",
"http://jsonplaceholder.typicode.com/posts/3"
]
tasks = [fetch_data(url) for url in urls]
results = await asyncio.gather(*tasks)
print("Fetched all data.")
asyncio.run(main())
Le code utilise aiohttp et asyncio Pour les demandes HTTP asynchrones. L’async fetch_data()
fonction:
- Prend une URL
- Ouvre une session Async HTTP
- Envoie un OBTENIR demande
- Attend la réponse et la lit comme du texte
- Imprime les 100 premiers caractères du résultat
- Renvoie les données
La fonction asyncio.gather ()
Dans l’exemple ci-dessus, nous utilisons asyncio.gather()
Fonction, qui est utilisée pour exécuter plusieurs tâches asynchrones en même temps. Il faut plusieurs objets attendables et les planifie pour s’exécuter simultanément.
Le await.asyncio.gather()
La fonction attend la fin des tâches données, puis renvoie leurs résultats en tant que liste, en préservant le même ordre que les tâches d’entrée.
Il commence de nombreuses tâches asynchrones en même temps au lieu d’attendre que l’on se termine avant de commencer la suivante. Si une tâche échoue, cela augmente l’erreur une fois toutes les tâches terminées.
La fonction asyncio.queue ()
L’autre scénario consiste à travailler avec un producteur et un consommateur. Le producteur produit des données et le consommateur le consomme. Pour cela, Asyncio fournit le asyncio.queue()
fonction. Il est sûr de fil, une file d’attente de premier entrée (FIFO). Il est utile de récupérer les données et de les traiter de manière synchrone.
import asyncio
import aiohttp
async def fetch_data(url, queue):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.text()
print(f"Fetched data from {url} :{data[:100]}...")
await queue.put(data)
async def process_data(queue):
while True:
data = await queue.get()
if data is None:
break
print(f"Processing data of length {len(data)}")
queue.task_done()
async def main():
urls = [
"http://jsonplaceholder.typicode.com/posts/1",
"http://jsonplaceholder.typicode.com/posts/2",
"http://jsonplaceholder.typicode.com/posts/3",
]
queue = asyncio.Queue()
consumer = asyncio.create_task(process_data(queue))
producers = [fetch_data(url, queue) for url in urls]
await asyncio.gather(*producers)
await queue.put(None)
await consumer
asyncio.run(main())
Le aysncio.Queue()
La fonction fonctionne de la manière suivante:
- Vous créez une file d’attente en utilisant
asyncio.Queue()
fonction - Les producteurs utilisent le
put()
fonction pour ajouter des éléments - Les consommateurs utilisent le
get()
fonction pour lire les éléments
La différence entre asyncio.gather
et asyncio.Queue
peut se résumer comme ceci:
asyncio.gather
- Il est utilisé lorsque vous souhaitez exécuter plusieurs coroutines simultanément.
- Vous énumérez ceux que vous voulez et cela les exécute tous ensemble, en attendant que tous se terminent.
- Il vous donne les résultats dans une liste.
- Il est utile lorsque vous avez un ensemble fixe de tâches que vous souhaitez exécuter en même temps.
asyncio.queue
- Il est utilisé lorsque vous voulez que différents sous-programmes se parlent et restent en synchronisation.
- Vous l’utilisez pour implémenter le modèle de consommation producteur.
- Il produit et consomme des données lorsqu’elle est disponible.
- Il est utile lorsque le nombre de tâches et de synchronisation n’est pas fixé.
Résumé
L’async est utilisé pour les opérations qui impliquent d’attendre, comme les tâches d’E / S, les appels d’API ou l’accès aux ressources externes. Il diffère du multithreading car la bibliothèque Asyncio exécute plusieurs coroutines sur un seul thread à l’aide d’une boucle d’événement. Si vous commencez par une IA générative, de nombreux SDK suivent le modèle asynchrone, donc avoir une compréhension solide d’Asyncio est utile.
J’espère que vous trouverez cet article utile. Merci d’avoir lu.
Source link