Threads et GIL
Comprendre les limites du multithreading Python
Threads et GIL est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.
Qu'est-ce qu'un thread ?
Un thread est un flux d'exécution distinct au sein d'un même processus. Le module threading de Python vous permet d'exécuter des fonctions de manière concurrente au sein d'un seul programme.
import threading
def worker():
print('hello from thread')
t = threading.Thread(target=worker)
t.start()
t.join()
print('main done')Démarrer plusieurs threads
Vous pouvez lancer plusieurs threads. Chacun exécute sa fonction cible. join() oblige le thread principal à attendre qu'un thread ait terminé.
import threading
def task(name):
print('task', name)
threads = [threading.Thread(target=task, args=(i,)) for i in range(3)]
for t in threads:
t.start()
for t in threads:
t.join()
print('all finished')Le verrou global de l'interpréteur
CPython possède un verrou global de l'interpréteur (GIL) : un seul thread à la fois exécute du bytecode Python. Les threads n'offrent donc pas de véritable accélération parallèle pour les calculs effectués uniquement en Python.
import sys
print('Running on:', sys.implementation.name)
print('Only one thread runs Python bytecode at a time due to the GIL')Quand les threads restent utiles
Les threads sont particulièrement efficaces pour les tâches limitées par les entrées-sorties : requêtes réseau, lectures sur disque et attentes. Lorsqu'un thread attend, le GIL est libéré et un autre peut s'exécuter.
import threading, time
def fake_io(name):
time.sleep(0.1)
print('done', name)
start = time.perf_counter()
ts = [threading.Thread(target=fake_io, args=(i,)) for i in range(3)]
for t in ts: t.start()
for t in ts: t.join()
print('elapsed about 0.1s, not 0.3s')Les tâches limitées par le processeur n'accélèrent pas
Pour les calculs lourds, l'ajout de threads ne les accélère pas, car le GIL les exécute séquentiellement. Pour les tâches limitées par le processeur, utilisez plutôt multiprocessing.
import threading
def burn():
total = 0
for i in range(1000000):
total += i
return total
t = threading.Thread(target=burn)
t.start()
t.join()
print('CPU-bound: threads share one core under the GIL')Threads démons
Un thread démon est automatiquement arrêté lorsque le programme principal se termine. Utilisez-le pour les tâches auxiliaires en arrière-plan que vous n'avez pas besoin d'attendre.
import threading, time
def background():
time.sleep(0.05)
print('background tick')
t = threading.Thread(target=background, daemon=True)
t.start()
t.join()
print('main exits')Nommer et identifier les threads
Chaque thread possède un nom et un identifiant. threading.current_thread() renvoie l'objet thread en cours d'exécution, ce qui est pratique pour la journalisation.
import threading
def show():
t = threading.current_thread()
print('running in', t.name)
t = threading.Thread(target=show, name='Worker-1')
t.start()
t.join()
print('main thread:', threading.current_thread().name)Créer une sous-classe de Thread
Au lieu de transmettre une cible, vous pouvez créer une sous-classe de Thread et redéfinir run(). Cette approche est utile lorsqu'un thread doit posséder son propre état.
import threading
class Greeter(threading.Thread):
def __init__(self, name):
super().__init__()
self.who = name
def run(self):
print('hi', self.who)
g = Greeter('Sam')
g.start()
g.join()Renvoyer des résultats depuis des threads
La valeur renvoyée par une fonction cible est ignorée. Pour recueillir les résultats, écrivez-les dans une structure partagée (vous découvrirez plus tard des outils plus sûrs, comme les files d'attente).
import threading
results = {}
def compute(key):
results[key] = key * key
ts = [threading.Thread(target=compute, args=(i,)) for i in range(4)]
for t in ts: t.start()
for t in ts: t.join()
print(results)Compter les threads actifs
threading.active_count() indique combien de threads sont actuellement actifs, thread principal compris.
import threading, time
def wait():
time.sleep(0.05)
ts = [threading.Thread(target=wait) for _ in range(2)]
for t in ts: t.start()
print('active now:', threading.active_count())
for t in ts: t.join()
print('active after join:', threading.active_count())Choisir entre threads et processus
Règle générale : utilisez les threads pour la concurrence limitée par les entrées-sorties et les processus pour le parallélisme limité par le processeur. Le GIL en est la raison.
tasks = {'download files': 'threads', 'crunch numbers': 'processes', 'call APIs': 'threads'}
for task, choice in tasks.items():
print(task, '->', choice)Vérification rapide
Testez votre compréhension des threads et du GIL.
Récapitulatif
Vous avez découvert les threads et le GIL :
- Les threads s'exécutent de manière concurrente au sein d'un même processus grâce à
threading.Thread. - Le GIL exécute le bytecode Python de manière séquentielle.
- Les threads sont utiles pour les tâches limitées par les entrées-sorties ; les processus, pour celles limitées par le processeur.
- Utilisez
start(),join(), les threads démons et la création de sous-classes.
Ensuite : gérer proprement les threads avec ThreadPoolExecutor.
Questions Fréquemment Posées
La leçon « Threads et GIL » est-elle gratuite ?
Oui — le texte complet de « Threads et GIL » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Threads et GIL » ?
Comprendre les limites du multithreading Python Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Python Academy ?
Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Threads et GIL » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?
Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.