_thread — API bas niveau de gestion de fils d'exécution


Ce module fournit les primitives de bas niveau pour travailler avec de multiples fils d'exécution (aussi appelés light-weight processes ou tasks) — plusieurs fils d'exécution de contrôle partagent leur espace de données global. Pour la synchronisation, de simples verrous (aussi appelés des mutexes ou des binary semaphores) sont fournis. Le module threading fournit une API de fils d'exécution de haut niveau, plus facile à utiliser et construite à partir de ce module.

Modifié dans la version 3.7: Ce module était optionnel, il est maintenant toujours disponible.

Ce module définit les constantes et les fonctions suivantes :

exception _thread.error

Levée lors d'erreurs spécifiques aux fils d'exécution.

Modifié dans la version 3.3: Ceci est à présent un synonyme de l'exception native RuntimeError.

_thread.LockType

C'est le type d'objets verrous.

_thread.start_new_thread(function, args[, kwargs])

Démarre un nouveau fils d'exécution et renvoie son identifiant. Ce fil d'exécution exécute la fonction function avec la liste d'arguments args (qui doit être un tuple). L'argument optionnel kwargs spécifie un dictionnaire d'arguments de mots clés.

Au renvoi de la fonction, le fil d'exécution quitte silencieusement.

Lorsque la fonction se termine avec une exception non gérée, sys.unraisablehook() est appelée pour gérer cette dernière. L'attribut object de l'argument hook est function. Par défaut, la trace d'appels est affichée puis le fil d'exécution se termine (mais les autres fils d'exécution continuent de s'exécuter).

Lorsque la fonction lève l'exception SystemExit, elle est ignorée silencieusement.

Modifié dans la version 3.8: sys.unraisablehook() est maintenant utilisée pour s'occuper des exceptions non gérées.

_thread.interrupt_main()

Simule l'effet d'un signal signal.SIGINT arrivant au fil d'exécution principal. Un fil d'exécution peut utiliser cette fonction pour interrompre le fil d'exécution principal.

Si le signal signal.SIGINT n'est pas géré par Python (s'il a été paramétré à signal.SIG_DFL ou signal.SIG_IGN), cette fonction ne fait rien.

_thread.exit()

Lève une exception SystemExit. Quand elle n'est pas interceptée, le fil d'exécution se terminera silencieusement.

_thread.allocate_lock()

Renvoie un nouveau verrou. Les méthodes des verrous sont décrites ci-dessous. Le verrou est initialement déverrouillé.

_thread.get_ident()

Renvoie l'« identifiant de fil » du fil d'exécution courant. C'est un entier non nul. Sa valeur n'a pas de signification directe ; il est destiné à être utilisé comme cookie magique, par exemple pour indexer un dictionnaire de données pour chaque fil. Les identifiants de fils peuvent être recyclés lorsqu'un fil d'exécution se termine et qu'un autre fil est créé.

_thread.get_native_id()

Renvoie l'identifiant natif complet assigné par le noyau du fil d'exécution actuel. C'est un entier non négatif. Sa valeur peut uniquement être utilisée pour identifier ce fil d'exécution à l'échelle du système (jusqu'à ce que le fil d'exécution se termine, après quoi la valeur peut être recyclée par le système d'exploitation).

Disponibilité : Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX.

Nouveau dans la version 3.8.

_thread.stack_size([size])

Renvoie la taille de la pile d'exécution utilisée lors de la création de nouveaux fils d'exécution. L'argument optionnel size spécifie la taille de pile à utiliser pour les fils créés ultérieurement, et doit être à 0 (pour utiliser la taille de la plate-forme ou la valeur configurée par défaut) ou un entier positif supérieur ou égal à 32 768 (32 Kio). Si size n'est pas spécifié, 0 est utilisé. Si la modification de la taille de la pile de fils n'est pas prise en charge, une exception RuntimeError est levée. Si la taille de la pile spécifiée n'est pas valide, une exception ValueError est levée et la taille de la pile n'est pas modifiée. 32 Kio est actuellement la valeur minimale de taille de la pile prise en charge pour garantir un espace de pile suffisant pour l'interpréteur lui-même. Notez que certaines plates-formes peuvent avoir des restrictions particulières sur les valeurs de taille de la pile, telles que l'exigence d'une taille de pile minimale > 32 Kio ou d'une allocation en multiples de la taille de page de la mémoire du système – la documentation de la plate-forme devrait être consultée pour plus d'informations (4 Kio sont courants ; en l'absence de renseignements plus spécifiques, l'approche suggérée est l'utilisation de multiples de 4 096 octets pour la taille de la pile).

Disponibilité : Windows et systèmes gérant les fils d'exécution POSIX.

_thread.TIMEOUT_MAX

La valeur maximale autorisée pour le paramètre timeout de la méthode Lock.acquire(). Préciser un délai d'attente supérieur à cette valeur lève une exception OverflowError.

Nouveau dans la version 3.2.

Les verrous ont les méthodes suivantes :

lock.acquire(waitflag=1, timeout=-1)

Sans aucun argument optionnel, cette méthode acquiert le verrou inconditionnellement, et si nécessaire attend jusqu'à ce qu'il soit relâché par un autre fil d'exécution (un seul fil d'exécution à la fois peut acquérir le verrou — c'est leur raison d'être).

Si l'argument waitflag, un entier, est présent, l'action dépend de sa valeur : si elle est de zéro, le verrou est seulement acquis s'il peut être acquis immédiatement, sans attendre, sinon le verrou est acquis inconditionnellement comme ci-dessus.

Si l'argument timeout, en virgule flottante, est présent et positif, il spécifie le temps d'attente maximum en secondes avant de renvoyer. Un argument timeout négatif spécifie une attente illimitée. Vous ne pouvez pas spécifier un timeout si waitflag est à zéro.

La valeur renvoyée est True si le verrou est acquis avec succès, sinon False.

Modifié dans la version 3.2: Le paramètre timeout est nouveau.

Modifié dans la version 3.2: Le verrou acquis peut maintenant être interrompu par des signaux sur POSIX.

lock.release()

Relâche le verrou. Le verrou doit avoir été acquis plus tôt, mais pas nécessairement par le même fil d'exécution.

lock.locked()

Renvoie le statut du verrou : True s'il a été acquis par certains fils d'exécution, sinon False.

En plus de ces méthodes, les objets verrous peuvent aussi être utilisés via l'instruction with, e.g. :

import _thread

a_lock = _thread.allocate_lock()

with a_lock:
    print("a_lock is locked while this executes")

Avertissements :

  • Les fils d'exécution interagissent étrangement avec les interruptions : l'exception KeyboardInterrupt sera reçue par un fil d'exécution arbitraire. (Quand le module signal est disponible, les interruptions vont toujours au fil d'exécution principal).

  • Appeler la fonction sys.exit() ou lever l'exception SystemExit est équivalent à appeler la fonction _thread.exit().

  • Il n'est pas possible d'interrompre la méthode acquire() sur un verrou — l'exception KeyboardInterrupt surviendra après que le verrou a été acquis.

  • Quand le fil d'exécution principal s'arrête, il est défini par le système si les autres fils d'exécution survivent. Sur beaucoup de systèmes, ils sont tués sans l'exécution des clauses tryfinally ou l'exécution des destructeurs d'objets.

  • Quand le fil d'exécution principal s'arrête, il ne fait pas son nettoyage habituel (excepté que les clauses tryfinally sont honorées) et les fichiers d'entrée/sortie standards ne sont pas nettoyés.