Подтвердить что ты не робот

Как найти идентификатор потока в Python

У меня есть многопоточная программа на Python и служебная функция writeLog(message), которая записывает метку времени, за которой следует сообщение. К сожалению, полученный файл журнала не указывает, какой поток генерирует какое сообщение.

Я хотел бы, чтобы writeLog() мог добавить что-то к сообщению, чтобы определить, какой поток его вызывает. Очевидно, я мог бы просто заставить потоки передавать эту информацию, но это было бы намного больше работы. Есть ли какой-нибудь поток, эквивалентный os.getpid() который я мог бы использовать?

4b9b3361

Ответ 2

Используя модуль logging, вы можете автоматически добавлять текущий идентификатор потока в каждую запись журнала. Просто используйте один из этих LogRecord ключей отображения в строке формата журнала:

% (thread) d: Идентификатор потока (если доступен).

% (threadName) s: Название темы (если доступно).

и настройте для него свой обработчик по умолчанию:

logging.basicConfig(format="%(threadName)s:%(message)s")

Ответ 3

Функция 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)

Ответ 4

Я видел примеры идентификаторов потоков, подобных этому:

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.

Ответ 6

Вы можете получить идентификатор текущего запущенного потока. Идентификатор можно использовать для других потоков, если текущий поток заканчивается.

Когда вы создаете экземпляр 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() возвращает текущий запущенный поток. Этот объект содержит всю информацию о потоке.

Ответ 7

Я создал несколько потоков в Python, я напечатал объекты потока, и я напечатал идентификатор, используя переменную ident. Я вижу, что все идентификаторы одинаковы:

<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>

Ответ 8

Как и @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, хотя.