0Pricing
Python Academy · Leçon

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.

Toutes les leçons de ce cours

  1. Threads et GIL
  2. ThreadPoolExecutor
  3. Les bases de multiprocessing
  4. Partager les données en toute sécurité
← Retour à Python Academy