Les threads en Python

Un thread est défini en informatique comme la plus petite unité pouvant être planifiée dans un système d’exploitation. Les threads sont normalement créés par un script ou d’un programme informatique (qui sont implémentées sur un seul processeur par le multitâche).
 
 
Les threads sont généralement contenus dans les processus. Plusieurs threads peuvent exister dans le même processus. Ces threads partagent la mémoire et l’état du processus. En d’autres termes: ils partagent le code ou les instructions et les valeurs de ses variables.
 


 
Il existe deux types de threads différents:

  • Les threads du noyau
  • Les threads utilisateur

Les threads du noyau font partie du système d’exploitation, tandis que les threads utilisateur ne sont pas implémentés dans le noyau.

D’une certaine manière, les threads utilisateur peuvent être considérés comme une extension du concept de fonction d’un langage de programmation. Un thread utilisateur est donc similaire à un appel de fonction ou de procédure. Mais il existe des différences par rapport aux fonctions régulières, en particulier le comportement de retour.

Chaque processus a au moins un thread, c’est-à-dire le processus lui-même. Un processus peut démarrer plusieurs threads. Le système d’exploitation exécute ces threads comme des « processus » parallèles. Sur une machine à processeur unique, ce parallélisme est obtenu par la programmation des threads ou le découpage temporel.
 
 

Avantages du multithreading:
  • Les programmes multithread peuvent s’exécuter plus rapidement sur les systèmes informatiques avec plusieurs processeurs, car ces threads peuvent être exécutés de manière vraiment simultanée.
  • Un programme peut rester réactif à la saisie. Cela est vrai à la fois sur un seul et sur plusieurs processeurs
  • Les threads d’un processus peuvent partager la mémoire des variables globales. Si une variable globale est modifiée dans un thread, cette modification est valide pour tous les threads. Un thread peut avoir des variables locales.

La gestion des threads est plus simple que la gestion des processus pour un système d’exploitation. C’est pourquoi ils sont parfois appelés processus légers.
 

Les threads en Python

Il existe deux modules qui prennent en charge l’utilisation des threads en Python: thread et threading.

Le module « thread » traite un thread comme une fonction, tandis que le module « threading » est implémenté de manière orientée objet, c’est-à-dire que chaque thread correspond à un objet.

Le module « thread » est considéré comme « obsolète » depuis assez longtemps. Les utilisateurs ont été encouragés à utiliser le module « threading » à la place. Ainsi, en Python 3, le module « thread » n’est plus disponible.

Le module « threading » s’appuie sur les fonctionnalités de bas niveau pour rendre le travail avec les threads encore plus facile et plus pythonique. L’utilisation de threads permet à un programme d’exécuter simultanément plusieurs opérations dans le même espace du processus.
 
 

Objets thread

La classe Thread possède une méthode start(), qui peut démarrer un Thread. Il déclenche la méthode run(), qui doit être surchargée. La méthode join() s’assure que le programme principal attend que tous les threads soient terminés.

La façon la plus simple d’utiliser un thread est de l’instancier avec une fonction définit par l’utilisateur et d’appeler start() pour le laisser commencer à fonctionner.

import threading

def job():
    """fonction job du thread"""
    print('Job')
    return

threads = []
for i in range(5):
    t = threading.Thread(target=job)
    threads.append(t)
    t.start()

Sortie:

Job
Job
Job
Job
Job

 

La méthode sleep()

L’exemple suivant stoppe le thread 5 secondes puis affiche un message:

import time
from threading import Thread

def sleeper(i):
    print("Le thread %d est en veille pendant 5 secondes" % i)
    time.sleep(5)
    print("Le thread %d s'est réveillé" % i) 

for i in range(10):
    t = Thread(target=sleeper, args=(i,))
    t.start()

Sortie:

Le thread 0 est en veille pendant 5 secondes
Le thread 1 est en veille pendant 5 secondes
Le thread 2 est en veille pendant 5 secondes
Le thread 3 est en veille pendant 5 secondes
Le thread 4 est en veille pendant 5 secondes
Le thread 5 est en veille pendant 5 secondes
Le thread 6 est en veille pendant 5 secondes
Le thread 7 est en veille pendant 5 secondes
Le thread 8 est en veille pendant 5 secondes
Le thread 9 est en veille pendant 5 secondes
Le thread 0 s'est réveillé
Le thread 1 s'est réveillé
Le thread 2 s'est réveillé
Le thread 3 s'est réveillé
Le thread 4 s'est réveillé
Le thread 5 s'est réveillé
Le thread 6 s'est réveillé
Le thread 7 s'est réveillé
Le thread 8 s'est réveillé
Le thread 9 s'est réveillé

 
 

Déterminer le Thread courant

L’utilisation d’arguments pour identifier ou nommer un thread est inutile. Chaque instance de thread a un nom avec une valeur par défaut qui peut être modifiée lors de la création du thread. La dénomination des threads est utile dans les processus serveur avec plusieurs threads de service gérant différentes opérations.

La plupart des programmes n’utilisent pas la méthode print() pour déboguer. Le module logging prend en charge l’incorporation du nom de thread dans chaque message de log. L’inclusion de noms de threads dans les messages de log facilite le suivi de ces messages jusqu’à leur source.

import logging
import threading
import time

logging.basicConfig(level=logging.DEBUG,
                    format='[%(levelname)s] (%(threadName)s) %(message)s',
                    )

def tcp():
    logging.debug('Starting')
    time.sleep(2)
    logging.debug('Exiting')

def udp():
    logging.debug('Starting')
    time.sleep(3)
    logging.debug('Exiting')

t = threading.Thread(name='UDP', target=udp)
u = threading.Thread(name='TCP', target=tcp)

t.start()
u.start()

Sortie:

[DEBUG] (UDP) Starting
[DEBUG] (TCP) Starting
[DEBUG] (TCP) Exiting
[DEBUG] (UDP) Exiting

 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *