Ответ 1
Работает threading.get_ident()
, или threading.current_thread().ident
(или threading.currentThread().ident
для Python <2.6).
У меня есть многопоточная программа на Python и служебная функция writeLog(message)
, которая записывает метку времени, за которой следует сообщение. К сожалению, полученный файл журнала не указывает, какой поток генерирует какое сообщение.
Я хотел бы, чтобы writeLog()
мог добавить что-то к сообщению, чтобы определить, какой поток его вызывает. Очевидно, я мог бы просто заставить потоки передавать эту информацию, но это было бы намного больше работы. Есть ли какой-нибудь поток, эквивалентный os.getpid()
который я мог бы использовать?
Работает threading.get_ident()
, или threading.current_thread().ident
(или threading.currentThread().ident
для Python <2.6).
Используя модуль logging, вы можете автоматически добавлять текущий идентификатор потока в каждую запись журнала. Просто используйте один из этих LogRecord ключей отображения в строке формата журнала:
% (thread) d: Идентификатор потока (если доступен).
% (threadName) s: Название темы (если доступно).
и настройте для него свой обработчик по умолчанию:
logging.basicConfig(format="%(threadName)s:%(message)s")
Функция thread.get_ident()
возвращает длинное целое число в Linux. Это не действительно идентификатор потока.
Я использую этот метод, чтобы действительно получить идентификатор потока в 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)
Я видел примеры идентификаторов потоков, подобных этому:
class myThread(threading.Thread):
def __init__(self, threadID, name, counter):
self.threadID = threadID
...
В docs docs перечислены атрибуты name
:
...
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.
Эта функциональность теперь поддерживается Python 3. 8+ :)
https://github.com/python/cpython/commit/4959c33d2555b89b494c678d99be81a65ee864b0
Вы можете получить идентификатор текущего запущенного потока. Идентификатор можно использовать для других потоков, если текущий поток заканчивается.
Когда вы создаете экземпляр Thread, для потока дается неявное имя, которое является шаблоном: номер потока
Имя не имеет значения, и имя не обязательно должно быть уникальным. Идентификатор всех запущенных потоков уникален.
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()
Функция threading.current_thread() возвращает текущий запущенный поток. Этот объект содержит всю информацию о потоке.
Я создал несколько потоков в Python, я напечатал объекты потока, и я напечатал идентификатор, используя переменную ident
. Я вижу, что все идентификаторы одинаковы:
<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>
Как и @brucexin, мне нужно было получить идентификатор потока на уровне ОС (который! = thread.get_ident()
) и использовать что-то вроде ниже, чтобы не зависеть от конкретных чисел и быть только для amd64:
---- 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)
а также
---- 8< ---- (test.py)
import pyximport; pyximport.install()
import xos
...
print 'my tid: %d' % xos.gettid()
это зависит от Cython, хотя.