Cet article couvre les bases du multithreading dans le langage de programmation Python. Juste comme multitraitement , le multithreading est un moyen de réaliser le multitâche. En multithreading, le concept de fils de discussion est utilisé. Comprenons d'abord le concept de fil en architecture informatique.
Qu'est-ce qu'un processus en Python ?
En informatique, un processus est une instance d'un programme informatique en cours d'exécution. Tout processus comporte 3 éléments de base :
- Un programme exécutable.
- Les données associées nécessaires au programme (variables, espace de travail, buffers, etc.)
- Le contexte d'exécution du programme (Etat du processus)
Une introduction au threading Python
UN fil est une entité au sein d'un processus dont l'exécution peut être planifiée. En outre, il s’agit de la plus petite unité de traitement pouvant être effectuée dans un système d’exploitation (Operating System). En termes simples, un thread est une séquence de telles instructions au sein d’un programme qui peut être exécutée indépendamment d’un autre code. Pour simplifier, vous pouvez supposer qu’un thread est simplement un sous-ensemble d’un processus ! Un fil de discussion contient toutes ces informations dans un Bloc de contrôle des threads (TCB) :
- Identifiant du fil : Un identifiant unique (TID) est attribué à chaque nouveau fil de discussion
- Pointeur de pile : Pointe vers la pile du thread dans le processus. La pile contient les variables locales sous la portée du thread.
- Compteur de programme: un registre qui stocke l'adresse de l'instruction en cours d'exécution par un thread.
- État du fil : peut être en cours d'exécution, prêt, en attente, en démarrage ou terminé.
- Ensemble de registres du fil : registres affectés au thread pour les calculs.
- Pointeur du processus parent : Un pointeur vers le bloc de contrôle de processus (PCB) du processus sur lequel réside le thread.
Considérez le diagramme ci-dessous pour comprendre la relation entre le processus et son fil :

Relation entre un processus et son thread
taille alpha bêta
Plusieurs threads peuvent exister au sein d'un même processus où :
- Chaque fil contient son propre ensemble de registres et variables locales (stockées dans la pile) .
- Tous les threads d'un partage de processus variables globales (stockées dans le tas) et le code de programme .
Considérez le diagramme ci-dessous pour comprendre comment plusieurs threads existent en mémoire :

Existence de plusieurs threads en mémoire
Une introduction au threading en Python
Multithreading est défini comme la capacité d'un processeur à exécuter plusieurs threads simultanément. Dans un processeur simple à cœur unique, cela est réalisé en utilisant une commutation fréquente entre les threads. Ceci est appelé changement de contexte . Lors du changement de contexte, l'état d'un thread est enregistré et l'état d'un autre thread est chargé chaque fois qu'une interruption (due aux E/S ou définie manuellement) a lieu. Le changement de contexte a lieu si fréquemment que tous les threads semblent s'exécuter en parallèle (c'est ce qu'on appelle multitâche ).
Considérez le diagramme ci-dessous dans lequel un processus contient deux threads actifs :

Multithreading
Multithreading en Python
Dans Python , le filetage Le module fournit une API très simple et intuitive pour générer plusieurs threads dans un programme. Essayons de comprendre le code multithread étape par étape.
Étape 1: Module d'importation
Tout d’abord, importez le module de threading.
import threading>
Étape 2: Créer un fil de discussion
Pour créer un nouveau fil, nous créons un objet du Fil classe. Il prend la « cible » et les « arguments » comme paramètres. Le cible est la fonction à exécuter par le thread alors que le les arguments sont les arguments à passer à la fonction cible.
trier un tableau en Java
t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>
Étape 3: Démarrer un fil de discussion
Pour démarrer un fil de discussion, nous utilisons le commencer() méthode de la classe Thread.
t1.start() t2.start()>
Étape 4: Terminer le fil de discussion Exécution
Une fois les threads démarrés, le programme actuel (vous pouvez le considérer comme un thread principal) continue également à s'exécuter. Afin d'arrêter l'exécution du programme en cours jusqu'à ce qu'un thread soit terminé, nous utilisons la rejoindre() méthode.
t1.join() t2.join()>
En conséquence, le programme actuel attendra d'abord l'achèvement de t1 et puis t2 . Une fois terminées, les instructions restantes du programme en cours sont exécutées.
Exemple:
Considérons un exemple simple utilisant un module de threading.
Ce code montre comment utiliser le module de thread de Python pour calculer simultanément le carré et le cube d'un nombre. Deux fils, t1> et t2> , sont créés pour effectuer ces calculs. Ils sont démarrés et leurs résultats sont imprimés en parallèle avant que le programme n'imprime Terminé ! quand les deux threads sont terminés. Le threading est utilisé pour obtenir le parallélisme et améliorer les performances du programme lors de tâches gourmandes en calcul.
Python3
import> threading> def> print_cube(num):> >print>(>'Cube: {}'> .>format>(num>*> num>*> num))> def> print_square(num):> >print>(>'Square: {}'> .>format>(num>*> num))> if> __name__>=>=>'__main__'>:> >t1>=> threading.Thread(target>=>print_square, args>=>(>10>,))> >t2>=> threading.Thread(target>=>print_cube, args>=>(>10>,))> >t1.start()> >t2.start()> >t1.join()> >t2.join()> >print>(>'Done!'>)> |
>
>
Sortir:
Square: 100 Cube: 1000 Done!>
Considérez le diagramme ci-dessous pour une meilleure compréhension du fonctionnement du programme ci-dessus :

Multithreading
Exemple:
Dans cet exemple, nous utilisons os.getpid() fonction pour obtenir l’ID du processus en cours. Nous utilisons threading.main_thread() fonction pour obtenir l’objet du thread principal. Dans des conditions normales, le thread principal est le thread à partir duquel l'interpréteur Python a été démarré. nom L'attribut de l'objet thread est utilisé pour obtenir le nom du thread. Ensuite, nous utilisons le threading.current_thread() fonction pour obtenir l’objet thread actuel.
Considérez le programme Python ci-dessous dans lequel nous imprimons le nom du thread et le processus correspondant pour chaque tâche.
comparer à Java
Ce code montre comment utiliser le module de threading de Python pour exécuter deux tâches simultanément. Le programme principal lance deux threads, t1> et t2> , chacun étant responsable de l’exécution d’une tâche spécifique. Les threads s'exécutent en parallèle et le code fournit des informations sur l'ID du processus et les noms des threads. Leos>Le module est utilisé pour accéder à l'ID du processus, et le ' threading'> Le module est utilisé pour gérer les threads et leur exécution.
Python3
chaîne remplacer tout java
import> threading> import> os> def> task1():> >print>(>'Task 1 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 1: {}'>.>format>(os.getpid()))> def> task2():> >print>(>'Task 2 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 2: {}'>.>format>(os.getpid()))> if> __name__>=>=> '__main__'>:> >print>(>'ID of process running main program: {}'>.>format>(os.getpid()))> >print>(>'Main thread name: {}'>.>format>(threading.current_thread().name))> >t1>=> threading.Thread(target>=>task1, name>=>'t1'>)> >t2>=> threading.Thread(target>=>task2, name>=>'t2'>)> >t1.start()> >t2.start()> >t1.join()> >t2.join()> |
>
>
Sortir:
ID of process running main program: 1141 Main thread name: MainThread Task 1 assigned to thread: t1 ID of process running task 1: 1141 Task 2 assigned to thread: t2 ID of process running task 2: 1141>
Le diagramme ci-dessous clarifie le concept ci-dessus :

Multithreading
C'était donc une brève introduction au multithreading en Python. Le prochain article de cette série couvre synchronisation entre plusieurs threads . Multithreading en Python | Ensemble 2 (synchronisation)
Pool de threads Python
Un pool de threads est un ensemble de threads créés à l’avance et pouvant être réutilisés pour exécuter plusieurs tâches. Le module concurrent.futures en Python fournit une classe ThreadPoolExecutor qui facilite la création et la gestion d'un pool de threads.
Dans cet exemple, nous définissons une fonction de travail qui s'exécutera dans un thread. Nous créons un ThreadPoolExecutor avec un maximum de 2 threads de travail. Nous soumettons ensuite deux tâches au pool en utilisant la méthode submit. Le pool gère l'exécution des tâches dans ses threads de travail. Nous utilisons la méthode d'arrêt pour attendre que toutes les tâches soient terminées avant que le thread principal ne continue.
Le multithreading peut vous aider à rendre vos programmes plus efficaces et plus réactifs. Cependant, il est important d’être prudent lorsque vous travaillez avec des threads pour éviter des problèmes tels que des conditions de concurrence critique et des blocages.
Ce code utilise un pool de threads créé avec concurrent.futures.ThreadPoolExecutor> pour exécuter deux tâches de travail simultanément. Le thread principal attend que les threads de travail aient fini d'utiliser pool.shutdown(wait=True)> . Cela permet un traitement parallèle efficace des tâches dans un environnement multithread.
Python3
générateur de valeurs aléatoires en Java
import> concurrent.futures> def> worker():> >print>(>'Worker thread running'>)> pool>=> concurrent.futures.ThreadPoolExecutor(max_workers>=>2>)> pool.submit(worker)> pool.submit(worker)> pool.shutdown(wait>=>True>)> print>(>'Main thread continuing to run'>)> |
>
>Sortir
Worker thread running Worker thread running Main thread continuing to run>