Multithreading en Python
Le multithreading fait référence à la technique consistant à exécuter plusieurs threads simultanément au sein d’un même processus. L’exécution simultanée vise à utiliser le plein potentiel des systèmes informatiques et à exécuter des tâches encore plus rapidement qu’elles le feraient habituellement.
Les threads sont remarquablement légers et ont une faible empreinte mémoire par rapport aux processus. Comme ils sont très légers, la création d’un nouveau thread est un processus rapide. Les threads en cours d’exécution nécessitent moins de ressources système, par exemple de la mémoire, pour s’exécuter.
Puisque les threads font partie d’un processus, ils partagent l’espace mémoire avec leur processus parent ou le processus qui les a créés. Le multithreading peut sembler trop impressionnant, mais toutes les paillettes ne sont pas dorées. Il faut être prudent lorsque l’on travaille avec des threads car se heurter à des blocages et à des conditions de concurrence est assez ordinaire. Malheureusement, en raison du GIL ou Global Interpreter Lock en Python, les threads créés par Python fournissent un entrelacement et sont exécutés séquentiellement mais pas parallèlement.
On peut découvrir un véritable parallélisme avec les threads dans d’autres langages de programmation tels que Java. Si l’on a encore besoin de bénéficier de plusieurs cœurs de processeur en utilisant Python, il faut envisager d’opter pour le multitraitement (la technique d’exécution de divers processus en parallèle).
Néanmoins, nous pouvons toujours effectuer du multithreading en Python dans une certaine mesure. Dans cet article, nous allons apprendre à effectuer du multithreading à l’aide de Python.
Multithreading en Python
Nous pouvons utiliser la bibliothèque threading
de Python pour effectuer du multithreading en Python. Il s’agit d’un module intégré qui est préinstallé avec Python officiel, et il vise à fournir un parallélisme basé sur les threads en Python. Pour en savoir plus sur ce module et ce qu’il propose, reportez-vous à la documentation officielle ici.
Voyons maintenant comment utiliser cette bibliothèque pour effectuer du multithreading. Reportez-vous au code Python suivant pour la même chose.
import threading
class MyThread(threading.Thread):
def __init__(self, low, high):
super(MyThread, self).__init__()
self.low = low
self.high = high
self.total = 0
def run(self):
for x in range(self.low, self.high):
self.total += x
def __str__(self):
return f"Low: {self.low} | High: {self.high}"
thread_one = MyThread(0, 500000)
thread_two = MyThread(5000000, 10000000)
thread_one.start()
thread_two.start()
thread_one.join()
thread_two.join()
result = thread_one.total + thread_two.total
print("Result:", result)
Production :
Result: 37624997250000
Le module threading
fournit une classe Thread
représentant une action effectuée sur un thread séparé. Une action peut être n’importe quoi, un calcul mathématique, une requête POST ou GET à un point de terminaison d’API, récupérer une sortie d’un modèle d’apprentissage automatique pré-formé, une tranche d’une analyse lourde, etc.
Une nouvelle classe, héritant de la classe Thread
, doit être créée, tout comme la classe MyThread
dans le code Python ci-dessus. Ensuite, la classe Thread
a une méthode run()
qui doit être remplacée. Cette fonction contient la tâche ou le calcul réel que le thread effectuera lorsqu’il sera activé.
Comme nous pouvons le voir, nous avons remplacé la fonction run()
dans le code Python ci-dessus. La fonction run()
ci-dessus boucle essentiellement dans la plage définie par les attributs de classe, low
et high
. Elle ajoute tous les entiers de la plage à un autre attribut de classe, total
.
Maintenant que nous en avons fini avec une brève description de la classe, comprenons comment le programme fonctionne. Reportez-vous aux étapes à venir.
- Deux threads, à savoir
thread_one
etthread_two
, sont générés ou créés. - Ensuite, la méthode
start()
des deux threads est appelée. La méthodestart()
exécute la méthoderun()
pour nous. - Ensuite, la méthode
join()
est appelée pour les deux threads. Cette méthode garantit que les deux threads attendent l’un l’autre avant de se terminer. Disons que le premier thread a terminé sa tâche5
secondes avant le deuxième thread. Si nous laissons le programme s’exécuter davantage, nous rencontrerons des bogues étranges car le deuxième thread n’est toujours pas accompli avec sa tâche. La méthodejoin()
s’assure qu’aucun thread ne se termine tant que tous les autres threads n’ont pas terminé leurs tâches. - Enfin, les résultats des deux threads sont additionnés et le résultat est imprimé sur la console.
Notez qu’il est obligatoire de faire en sorte qu’un thread invoqué attende que d’autres threads terminent leur exécution ; sinon, on peut rencontrer des résultats erronés et des erreurs.
Pour en savoir plus sur la classe Thread
, reportez-vous à la documentation officielle ici.