Comment trouver un identifiant de fil en Python
-
06-09-2019 - |
Question
J'ai un programme Python multi-threading, et une fonction d'utilité, writeLog(message)
, qui écrit un horodatage suivi du message. Malheureusement, le fichier journal résultant ne donne aucune indication dont fil génère quel message.
Je voudrais writeLog()
pouvoir ajouter quelque chose au message pour identifier le fil est l'appeler. Il est évident que je pouvais faire les fils passent cette information, mais ce serait beaucoup plus de travail. Y at-il un fil équivalent de os.getpid()
que je pourrais utiliser?
La solution
threading.get_ident()
fonctionne, ou threading.current_thread().ident
(ou threading.currentThread().ident
pour python <2,6)
Autres conseils
Utilisation de l'exploitation forestière de rel="noreferrer"> module, vous pouvez ajouter automatiquement l'identifiant de thread en cours dans chaque entrée de journal . Il suffit d'utiliser l'un de ces LogRecord clés de mapping dans votre chaîne de format de l'enregistreur:
% (fil) d. ID de thread (le cas échéant)
% (threadName) s. Nom du thread (le cas échéant)
et configurer votre gestionnaire par défaut avec elle:
logging.basicConfig(format="%(threadName)s:%(message)s")
La fonction retourne thread.get_ident()
un entier long sur Linux. Ce n'est pas vraiment un identifiant de fil.
J'utilise cette méthode pour vraiment l'ID de fil sur Linux:
import ctypes
libc = ctypes.cdll.LoadLibrary('libc.so.6')
# System dependent, see e.g. /usr/include/x86_64-linux-gnu/asm/unistd_64.h
SYS_gettid = 186
def getThreadId():
"""Returns OS thread id - Specific to Linux"""
return libc.syscall(SYS_gettid)
J'ai vu des exemples d'ID de fil comme celui-ci:
class myThread(threading.Thread):
def __init__(self, threadID, name, counter):
self.threadID = threadID
...
enfilant les listes du module docs name
attribut ainsi:
...
A thread has a name.
The name can be passed to the constructor,
and read or changed through the name attribute.
...
Thread.name
A string used for identification purposes only.
It has no semantics. Multiple threads may
be given the same name. The initial name is set by the constructor.
Vous pouvez obtenir le ident du fil conducteur en cours. Le ident peut être réutilisée pour d'autres fils, si le fil de courant se termine.
Lorsque vous cageot une instance de discussion, un nom est donné implicitement au fil, qui est le modèle: Discussion numéro
Le nom n'a pas de sens et le nom ne doit pas être unique. Le ident de tous les threads en cours d'exécution est unique.
import threading
def worker():
print(threading.current_thread().name)
print(threading.get_ident())
threading.Thread(target=worker).start()
threading.Thread(target=worker, name='foo').start()
Le threading.current_thread () la fonction retourne le fil conducteur de courant. Cet objet contient l'ensemble des informations du fil.
Cette fonctionnalité est désormais pris en charge par Python supérieure à 3,8:)
https://github.com/python/cpython/commit/4959c33d2555b89b494c678d99be81a65ee864b0
I créé plusieurs threads dans le python, j'imprimé les objets filetés, et je l'imprimé id en utilisant la variable d'ident
. Je vois tous les ids sont les mêmes:
<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>
De même pour @brucexin je besoin d'obtenir l'identificateur de fil au niveau du système d'exploitation (qui = thread.get_ident()
!) Et utiliser quelque chose comme ci-dessous ne pas dépendre des nombres particuliers et être amd64 uniquement:
---- 8< ---- (xos.pyx)
"""module xos complements standard module os"""
cdef extern from "<sys/syscall.h>":
long syscall(long number, ...)
const int SYS_gettid
# gettid returns current OS thread identifier.
def gettid():
return syscall(SYS_gettid)
et
---- 8< ---- (test.py)
import pyximport; pyximport.install()
import xos
...
print 'my tid: %d' % xos.gettid()
cela dépend Cython bien.