Table des matières
Points clés à retenir
- La concurrence et le parallélisme sont des principes fondamentaux de l’exécution des tâches en informatique, chacun ayant ses caractéristiques distinctes.
- La concurrence permet une utilisation efficace des ressources et une meilleure réactivité des applications, tandis que le parallélisme est crucial pour des performances et une évolutivité optimales.
- Python fournit des options pour gérer la concurrence, telles que le threading et la programmation asynchrone avec asyncio, ainsi que le parallélisme à l’aide du module multitraitement.
La concurrence et le parallélisme sont deux techniques qui vous permettent d’exécuter plusieurs programmes simultanément. Python propose plusieurs options pour gérer les tâches simultanément et en parallèle, ce qui peut prêter à confusion.
Explorez les outils et bibliothèques disponibles pour implémenter correctement la concurrence et le parallélisme dans Python, et en quoi ils diffèrent.
Comprendre la concurrence et le parallélisme
La concurrence et le parallélisme font référence à deux principes fondamentaux de l’exécution des tâches en informatique. Chacun a ses caractéristiques distinctes.
L’importance de la concurrence et du parallélisme
La nécessité de la concurrence et du parallélisme dans l’informatique ne peut être surestimée. Voici pourquoi ces techniques sont importantes :
Concurrence en Python
Vous pouvez obtenir la concurrence en Python en utilisant le threading et la programmation asynchrone avec la bibliothèque asyncio.
Threading en Python
Le threading est un mécanisme de concurrence Python qui vous permet de créer et de gérer des tâches au sein d’un seul processus. Les threads conviennent à certains types de tâches, en particulier celles qui sont liées aux E/S et peuvent bénéficier d’une exécution simultanée.
Le module de thread de Python fournit une interface de haut niveau pour créer et gérer des threads. Bien que le GIL (Global Interpreter Lock) limite les threads en termes de véritable parallélisme, ils peuvent toujours atteindre la concurrence en entrelaçant efficacement les tâches.
Le code ci-dessous montre un exemple d’implémentation de la concurrence à l’aide de threads. Il utilise la bibliothèque de requêtes Python pour envoyer une requête HTTP, une tâche courante de blocage d’E/S. Il utilise également le module time pour calculer le temps d’exécution.
import requests
import time
import threadingurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
def download_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")
start_time = time.time()for url in urls:
download_url(url)end_time = time.time()
print(f"Sequential download took {end_time - start_time:.2f} seconds\n")
start_time = time.time()
threads = []for url in urls:
thread = threading.Thread(target=download_url, args=(url,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()end_time = time.time()
print(f"Threaded download took {end_time - start_time:.2f} seconds")
En exécutant ce programme, vous devriez voir à quel point les requêtes threadées sont plus rapides que les requêtes séquentielles. Bien que la différence ne soit qu’une fraction de seconde, vous obtenez une idée claire de l’amélioration des performances lors de l’utilisation de threads pour des tâches liées aux E/S.
Programmation asynchrone avec Asyncio
asyncio fournit une boucle d’événements qui gère les tâches asynchrones appelées coroutines. Les coroutines sont des fonctions que vous pouvez suspendre et reprendre, ce qui les rend idéales pour les tâches liées aux E/S. La bibliothèque est particulièrement utile pour les scénarios dans lesquels les tâches impliquent l’attente de ressources externes, telles que les requêtes réseau.
Vous pouvez modifier l’exemple d’envoi de requête précédent pour fonctionner avec asyncio :
import asyncio
import aiohttp
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
async def download_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.text()
print(f"Downloaded {url} - Status Code: {response.status}")
async def main():
tasks = [download_url(url) for url in urls]
await asyncio.gather(*tasks)start_time = time.time()
asyncio.run(main())end_time = time.time()
print(f"Asyncio download took {end_time - start_time:.2f} seconds")
À l’aide du code, vous pouvez télécharger des pages Web simultanément à l’aide d’asyncio et profiter des opérations d’E/S asynchrones. Cela peut être plus efficace que le threading pour les tâches liées aux E/S.
Parallélisme en Python
Vous pouvez implémenter le parallélisme en utilisant Le module multitraitement de Pythonqui vous permet de profiter pleinement des processeurs multicœurs.
Multitraitement en Python
Le module multitraitement de Python fournit un moyen d’obtenir le parallélisme en créant des processus distincts, chacun avec son propre interpréteur Python et son propre espace mémoire. Cela contourne efficacement le Global Interpreter Lock (GIL), ce qui le rend adapté aux tâches liées au processeur.
import requests
import multiprocessing
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
def download_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")def main():
num_processes = len(urls)
pool = multiprocessing.Pool(processes=num_processes)start_time = time.time()
pool.map(download_url, urls)
end_time = time.time()
pool.close()
pool.join()print(f"Multiprocessing download took {end_time-start_time:.2f} seconds")
main()
Dans cet exemple, le multitraitement génère plusieurs processus, permettant à la fonction download_url de s’exécuter en parallèle.
Quand utiliser la concurrence ou le parallélisme
Le choix entre la concurrence et le parallélisme dépend de la nature de vos tâches et des ressources matérielles disponibles.
Vous pouvez utiliser la simultanéité lorsque vous traitez des tâches liées aux E/S, telles que la lecture et l’écriture dans des fichiers ou l’exécution de requêtes réseau, et lorsque les contraintes de mémoire sont un problème.
Utilisez le multitraitement lorsque vous avez des tâches liées au processeur qui peuvent bénéficier d’un véritable parallélisme et lorsque vous disposez d’une isolation robuste entre les tâches, où l’échec d’une tâche ne devrait pas avoir d’impact sur les autres.
Profitez de la concurrence et du parallélisme
Le parallélisme et la concurrence sont des moyens efficaces d’améliorer la réactivité et les performances de votre code Python. Il est important de comprendre les différences entre ces concepts et de sélectionner la stratégie la plus efficace.
Python propose les outils et modules dont vous avez besoin pour rendre votre code plus efficace grâce à la concurrence ou au parallélisme, que vous travailliez avec des processus liés au processeur ou aux E/S.