Python - Communication Inter-Thread
Bonjour, futurs sorciers Python !aujourd'hui, nous allons entamer un voyage passionnant dans le monde de la communication inter-thread en Python. Ne vous inquiétez pas si vous êtes nouveau dans la programmation – je serai votre guide amical, expliquant tout étape par étape. Alors, plongeons-y !
Qu'est-ce que la Communication Inter-Thread ?
Avant d'aller dans les détails, comprenons ce qu'est la communication inter-thread. Imaginez que vous faites partie d'une équipe travaillant sur un grand projet. Vous travaillez tous sur des parties différentes, mais parfois, vous avez besoin de partager des informations ou de coordonner vos efforts. C'est exactement ce que font les threads dans un programme, et la communication inter-thread est comment ils "parlent" les uns aux autres.
L'Objet Événement
Commençons par l'une des manières les plus simples pour les threads de communiquer : l'objet Événement.
Qu'est-ce qu'un Objet Événement ?
Un objet Événement est comme un drapeau qui peut être positionné ou effacé. Les threads peuvent attendre que ce drapeau soit positionné avant de continuer. C'est un peu comme attendre pour un feu vert avant de traverser la rue.
Comment Utiliser l'Objet Événement
Regardons un exemple simple :
import threading
import time
def waiter(event):
print("Serveur : Je attend que l'événement soit défini...")
event.wait()
print("Serveur : L'événement a été défini ! Je peux continuer maintenant.")
def setter(event):
print("Définisseur : Je vais définir l'événement dans 3 secondes...")
time.sleep(3)
event.set()
print("Définisseur : J'ai défini l'événement !")
# Créer un objet Événement
e = threading.Event()
# Créer et démarrer des threads
t1 = threading.Thread(target=waiter, args=(e,))
t2 = threading.Thread(target=setter, args=(e,))
t1.start()
t2.start()
# Attendre que les deux threads se terminent
t1.join()
t2.join()
print("Thread principal : Tout est terminé !")
Analysons cela :
- Nous importons le module
threading
pour créer des threads et le moduletime
pour ajouter des délais. - Nous définissons deux fonctions :
waiter
etsetter
. - La fonction
waiter
attend que l'événement soit défini en utilisantevent.wait()
. - La fonction
setter
attend 3 secondes (simulant du travail) puis définit l'événement en utilisantevent.set()
. - Nous créons un objet Événement
e
. - Nous créons deux threads, un pour chaque fonction, en passant l'objet Événement aux deux.
- Nous démarrons les deux threads puis utilisons
join()
pour les attendre.
Lorsque vous exécutez cela, vous verrez le serveur attendre, puis après 3 secondes, le définitisseur défini l'événement, et le serveur continue.
L'Objet Condition
Maintenant, augmentons notre niveau et regardons l'objet Condition. C'est comme le cousin plus sophistiqué de l'objet Événement.
Qu'est-ce qu'un Objet Condition ?
Un objet Condition permet aux threads d'attendre que certaines conditions deviennent vraies. C'est comme attendre qu'une personne spécifique arrive à une fête avant de commencer les jeux.
Comment Utiliser l'Objet Condition
Voici un exemple d'utilisation d'un objet Condition :
import threading
import time
import random
# Ressource partagée
items = []
condition = threading.Condition()
def producer():
global items
for i in range(5):
time.sleep(random.random()) # Simuler des temps de production variables
with condition:
items.append(f"Item {i}")
print(f"Producteur a ajouté Item {i}")
condition.notify() # Informer le consommateur qu'un élément est disponible
def consumer():
global items
while True:
with condition:
while not items:
print("Consommateur attend...")
condition.wait()
item = items.pop(0)
print(f"Consommateur a enlevé {item}")
time.sleep(random.random()) # Simuler des temps de consommation variables
# Créer et démarrer des threads
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
producer_thread.start()
consumer_thread.start()
# Attendre que le producteur se termine
producer_thread.join()
# Arrêter le consommateur (il est dans une boucle infinie)
consumer_thread.daemon = True
Analysons cela :
- Nous créons une ressource partagée
items
et un objet Condition. - La fonction
producer
ajoute des éléments à la liste et informe le consommateur. - La fonction
consumer
attend que des éléments soient disponibles, puis les retire et les "consomme". - Nous utilisons
with condition:
pour acquérir et libérer le verrou de la condition automatiquement. -
condition.wait()
libère le verrou et attend une notification. -
condition.notify()
réveille un thread en attente.
Cet exemple démontre une situation classique de producteur-consommateur, où un thread produit des éléments et un autre les consomme.
Comparaison des Objets Événement et Condition
Voici une comparaison rapide des objets Événement et Condition :
Fonctionnalité | Événement | Condition |
---|---|---|
But | Signalement simple | Synchronisation complexe |
État | Binaire (défini/effacé) | Peut avoir plusieurs états |
Attente | Les threads attendent que l'événement soit défini | Les threads attendent des conditions spécifiques |
Notification | Tous les threads en attente sont notifiés | Peut notifier un ou tous les threads en attente |
Cas d'utilisation | Scénarios "go/no-go" simples | Problèmes producteur-consommateur, synchronisation complexe |
Conclusion
Félicitations ! Vous venez de faire vos premiers pas dans le monde de la communication inter-thread en Python. Nous avons couvert l'objet Événement pour le signalement simple et l'objet Condition pour des scénarios de synchronisation plus complexes.
N'oubliez pas, comme pour l'apprentissage de toute nouvelle langue, la pratique fait le maître. Essayez d'écrire vos propres programmes utilisant ces objets. Peut-être créez un système de chat simple où les threads représentent des utilisateurs différents, ou simulatez un système de feux tricolores utilisant des événements.
La communication inter-thread peut sembler délicate au début, mais avec du temps et de la pratique, vous orchestrerez des threads comme un maestro dirige une orchestra. Continuez à coder, à apprendre, et surtout, amusez-vous !
Credits: Image by storyset