Comprendre le multi-traitement en Python : Un guide simplifié
Vous exécutez des applications ou des tâches de traitement de données à forte intensité de ressources ? Les serveurs dédiés d’AlexHost fournissent l’environnement parfait pour exploiter la puissance du multiprocessing en Python. Avec des processeurs de haute performance, des ressources dédiées et une infrastructure robuste, AlexHost s’assure que vos applications fonctionnent efficacement, même sous de lourdes charges de calcul. Que vous traitiez des données, exécutiez des simulations ou déployiez des modèles d’apprentissage automatique, les solutions d’AlexHost sont conçues pour maximiser votre productivité.
Le module multiprocessus de Python vous permet d’exécuter plusieurs processus simultanément, ce qui permet d’utiliser plusieurs cœurs de CPU et d’améliorer les performances des tâches liées au CPU. Cela s’avère particulièrement utile pour les tâches à forte intensité de calcul, telles que le traitement de données, l’apprentissage automatique ou les simulations. Ce guide fournit une explication simplifiée du fonctionnement du multiprocessus en Python et de son utilisation efficace.
Pourquoi utiliser le multiprocessus ?
Python utilise un verrouillage global de l’interpréteur (GIL), qui ne permet qu’à un seul thread d’exécuter le bytecode Python à la fois. Il est donc difficile d’utiliser le multithreading pour les tâches liées au processeur, puisqu’un seul thread peut s’exécuter à la fois, même sur un processeur multicœur. Le multiprocessing, en revanche, crée des espaces mémoire distincts pour chaque processus, ce qui permet à chaque processus de s’exécuter en parallèle et d’utiliser pleinement plusieurs cœurs de l’unité centrale.
Principales différences entre le multiprocessus et le multithreading :
- Le multiprocessus : Utilise des espaces mémoire distincts pour chaque processus, contourne la GIL et permet un véritable parallélisme.
- Multithreading : Partage l’espace mémoire entre les threads mais est limité par la GIL en Python, ce qui le rend plus adapté aux tâches liées aux E/S (comme la lecture/écriture de fichiers ou les requêtes réseau).
Premiers pas avec le module multiprocessing
Le module multiprocessus de Python permet de créer et de gérer plusieurs processus de différentes manières. Vous trouverez ci-dessous quelques-uns des concepts clés et la manière de les utiliser :
Importation du module
Pour utiliser le multiprocessing, il faut importer le module :
Concepts de base du multiprocessus
- Processus : Un processus est une instance indépendante d’un programme. Dans le contexte de Python, chaque processus dispose de son propre espace mémoire.
- Pool : Un pool permet de gérer plusieurs processus avec un nombre fixe de processus travailleurs.
- File d’attente : Une file d’attente est utilisée pour la communication entre les processus.
- Lock (verrou) : Un verrou est utilisé pour empêcher les processus d’accéder simultanément aux ressources partagées.
Exemple 1 : Création d’un processus simple
La façon la plus simple de créer un processus est d’utiliser la classe Process. Voici un exemple simple :
from multiprocessing import Process
def print_numbers() :
for i in range(5) :
print(f “Nombre : {i}”)
if __name__ == “__main__” :
# Créer un processus
process = Process(target=print_numbers)
# Démarrer le processus
process.start()
# Attendre la fin du processus
process.join()
print(“Processus terminé.”)
- Processus : La classe Process permet de créer un nouveau processus.
- target (cible) : L’argument target spécifie la fonction que le processus doit exécuter.
- start() : Démarre le processus.
- join() : Attend que le processus se termine avant de passer au reste du code.
Dans cet exemple, la fonction print_numbers sera exécutée dans un processus distinct, ce qui permettra au programme principal de s’exécuter simultanément.
Exemple 2 : Utilisation de multiprocessing.Pool
La classe Pool est utile lorsque vous souhaitez gérer un pool de processus travailleurs et appliquer une fonction à plusieurs éléments de données en parallèle. Voici un exemple :
from multiprocessing import Pool
def square_number(n) :
return n * n
if __name__ == “__main__” :
# Création d’un pool avec 4 processus
avec Pool(4) as pool :
nombres = [1, 2, 3, 4, 5]
# Utiliser pool.map() pour appliquer la fonction à chaque élément de la liste
résultats = pool.map(nombre_carré, nombres)
print(f “Nombres au carré : {résultats}”)
- Pool : Crée un pool de processus de travail. Dans ce cas, il crée 4 processus.
- map() : La fonction map prend une fonction et un itérable (comme une liste) et applique la fonction à chaque élément en parallèle.
Cet exemple met au carré chaque nombre de la liste des nombres en utilisant 4 processus parallèles. La fonction pool.map() répartit le travail entre les processus disponibles et renvoie les résultats sous forme de liste.
Exemple 3 : Utilisation d’une file d’attente pour la communication inter-processus
Si vous avez besoin que les processus communiquent ou partagent des données, vous pouvez utiliser une file d’attente. Cela est particulièrement utile dans le cas d’un scénario producteur-consommateur.
from multiprocessing import Process, Queue
def producer(queue) :
for i in range(5) :
queue.put(i)
print(f “Produit : {i}”)
def consumer(queue) :
while not queue.empty() :
item = queue.get()
print(f “Consommé : {item}”)
if __name__ == “__main__” :
queue = Queue()
# Créer les processus producteur et consommateur
producer_process = Process(target=producer, args=(queue,))
consumer_process = Process(target=consumer, args=(queue,))
# Démarrer les deux processus
producer_process.start()
processus_consommateur.start()
# Attendre que les deux processus se terminent
producer_process.join()
consumer_process.join()
print(“Tous les éléments ont été traités.”)
- File d’attente : Une file d’attente est utilisée pour transmettre des données entre les processus.
- put() : Ajoute un élément à la file d’attente.
- get() : Récupère un élément de la file d’attente.
Dans cet exemple, le producteur ajoute des éléments à la file d’attente, tandis que le consommateur récupère et traite ces éléments.
Exemple 4 : Utilisation de verrous pour éviter les conditions de course
Lorsque plusieurs processus partagent une ressource (comme un fichier ou une variable), vous pouvez rencontrer des conditions de course, où les processus essaient d’accéder à la ressource en même temps. Vous pouvez utiliser un verrou pour vous assurer qu’un seul processus peut accéder à la ressource à la fois.
from multiprocessing import Process, Lock
def print_numbers(lock) :
lock.acquire()
try :
for i in range(5) :
print(f “Nombre : {i}”)
finally :
lock.release()
si __name__ == “__main__” :
lock = Lock()
# Créer deux processus
process1 = Process(target=print_numbers, args=(lock,))
process2 = Process(target=print_numbers, args=(lock,))
# Démarrer les processus
process1.start()
process2.start()
# Attendre que les deux processus se terminent
process1.join()
process2.join()
print(“Les deux processus sont terminés.”)
- Verrou : Permet de s’assurer qu’un seul processus peut accéder à une section critique du code à la fois.
- acquire() : Acquiert le verrou.
- release() : Libère le verrou.
Dans cet exemple, le verrou empêche le processus 1 et le processus 2 d’imprimer des nombres simultanément, ce qui garantit que la sortie n’est pas entrelacée.
Quand utiliser le multitraitement ?
- Tâches liées au processeur : Utilisez le multiprocessus pour les tâches qui nécessitent beaucoup de calculs, comme les simulations numériques, le traitement des données ou le cryptage.
- Traitement parallèle : Lorsque vous devez effectuer la même opération sur plusieurs données, comme le traitement d’une grande liste de fichiers.
- Isolation des ressources : Lorsque chaque processus a besoin de son propre espace mémoire ou doit être complètement isolé des autres.
Conclusion
Le multiprocessus en Python est un moyen puissant d’exécuter plusieurs processus en parallèle, ce qui le rend idéal pour les tâches liées au processeur. En comprenant les concepts de base des processus, des pools, des files d’attente et des verrous, vous pouvez concevoir des programmes parallèles efficaces et performants. Que vous ayez besoin de traiter de grands ensembles de données, d’effectuer des calculs intensifs ou de gérer la communication inter-processus, le module multiprocessus de Python vous fournit les outils dont vous avez besoin.