Como encontrar um ID de segmento em Python
-
06-09-2019 - |
Pergunta
Eu tenho um programa multi-threading Python, e uma função de utilidade, writeLog(message)
, que escreve um timestamp seguido da mensagem. Infelizmente, o ficheiro de registo resultante não dá qualquer indicação de que está a gerar rosca que mensagem.
Gostaria writeLog()
para ser capaz de acrescentar algo à mensagem para identificar qual thread é chamá-lo. Obviamente, eu poderia apenas fazer os fios passar essa informação, mas que seria muito mais trabalho. Existe algum equivalente fio de os.getpid()
que eu poderia usar?
Solução
threading.get_ident()
funciona, ou threading.current_thread().ident
(ou threading.currentThread().ident
para Python <. 2.6)
Outras dicas
Usando o registro módulo você pode adicionar automaticamente o identificador thread atual em cada entrada de log . Basta usar uma destas teclas LogRecord mapeamento em sua cadeia de formato logger:
% (thread) d:. ID Thread (se disponível)
% (threadName) s:. nome da linha (se disponível)
e configurar o manipulador padrão com ele:
logging.basicConfig(format="%(threadName)s:%(message)s")
A função thread.get_ident()
retorna um inteiro longo no Linux. Não é realmente um identificador do tópico.
Eu uso este método para realmente obter o identificador do tópico no 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)
Eu vi exemplos de IDs de rosca como esta:
class myThread(threading.Thread):
def __init__(self, threadID, name, counter):
self.threadID = threadID
...
O rosqueamento módulo docs listas atributo name
assim:
...
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.
Você pode obter o ident do segmento em execução atual. A ident poderia ser reutilizado para outros tópicos, se as extremidades de fio atual.
Quando você caixote uma instância de Thread, um nome é dado implícita para o segmento, que é o padrão: Thread-número
O nome não tem significado e o nome não tem que ser único. A ident de todas as threads em execução é único.
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()
O threading.current_thread function () retorna o segmento em execução atual. Este objeto contém toda a informação da linha.
Esta funcionalidade é agora suportado pelo Python 3.8+:)
https://github.com/python/cpython/commit/4959c33d2555b89b494c678d99be81a65ee864b0
Eu criei vários segmentos em Python, eu imprimi os objetos de rosca, e eu imprimi o id usando a variável ident
. Eu vejo todos os ids são os mesmos:
<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>
À semelhança do @brucexin eu precisava para obter identificador de thread-nível do sistema operacional e usar algo como abaixo para não depender de números específicos e sendo amd64-only (que = thread.get_ident()
!):
---- 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)
e
---- 8< ---- (test.py)
import pyximport; pyximport.install()
import xos
...
print 'my tid: %d' % xos.gettid()
isso depende Cython embora.