파이썬에서 스레드 ID를 찾는 방법


179

멀티 스레딩 Python 프로그램과 writeLog(message)메시지가 뒤 따르는 타임 스탬프를 쓰는 유틸리티 함수 가 있습니다. 불행하게도, 결과 로그 파일은 어떤 스레드가 어떤 메시지를 생성하는지에 대한 표시를 제공하지 않습니다.

writeLog()메시지를 호출하는 스레드를 식별하기 위해 메시지에 무언가를 추가하고 싶습니다 . 분명히 스레드 가이 정보를 전달하도록 할 수는 있지만 훨씬 더 많은 작업이 될 것입니다. os.getpid()내가 사용할 수 있는 스레드가 있습니까?

답변:


227

threading.get_ident()작동하거나 threading.current_thread().ident(또는 threading.currentThread().identPython <2.6).


3
니콜라스 링크 수정 최근에 문서의 제목 위에 마우스를 올리면 오른쪽에 작은 빨간색 기호가 나타납니다. 문서에 대한보다 구체적인 링크를 위해 복사하여 붙여 넣기 :-)
Jon Cage

2
Jython을 사용하는 경우 threading.currentThread()2.5 버전에서 (camel_case가 아닌 camelCase) 를 원합니다 .
Cam Jackson

3
에 파이썬 문서, 조심 @CharlesAnderson Thread.name이 말하는 "이름 -. 문자열은 식별 목적으로 만 사용 그것은 아무 의미가 없다. 여러 스레드가 같은 이름을 부여 할 수있다. 초기 이름은 생성자에 의해 설정됩니다."
drevicko

7
또한 OS X의 Python 2.5 및 2.6에서는 threading.current_thread().ident부적절한 버그가있는 것으로 보입니다 None. 아마도 thread.get_ident()파이썬 2와 threading.current_thread().ident파이썬 3에서 사용하는 것이 합리적 일 것입니다.
Nicholas Riley

5
내 대답의 이전 버전 언급했습니다 thread.get_ident()( threading.get_ident()Python 3.3에 추가되었습니다-설명서 링크를 따르십시오).
Nicholas Riley

68

로깅 모듈을 사용하면 각 로그 항목에 현재 스레드 식별자를 자동으로 추가 할 수 있습니다. 로거 형식 문자열에서 다음 LogRecord 매핑 키 중 하나를 사용 하십시오.

% (thread) d : 스레드 ID (사용 가능한 경우).

% (threadName) s : 스레드 이름 (사용 가능한 경우).

기본 핸들러를 설정하십시오.

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

로거를 사용하고 있습니다. 그래서 당신이 대답하는 것이 가장 간단한 해결책이라고 생각합니다. 그러나 이것을 <concurrent.futures.thread.ThreadPoolExecutor object at 0x7f00f882a438>_2 스레드 이름으로 얻고 있습니다. 이 호출 내 스레드 수 있다는 것이다
라비 샹카 레디를

22

thread.get_ident()함수는 Linux에서 긴 정수를 반환합니다. 실제로 스레드 ID가 아닙니다.

이 방법 을 사용 하여 Linux에서 스레드 ID를 실제로 얻습니다.

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)

이것은 때때로 사용될 수 있지만 휴대용이 아닙니다
Piyush Kansal

3
링크가 나빠질 경우 방문자에게 계속 유용하도록이 답변을 편집 해 주시겠습니까?
josliber

스레드 클래스의 start () 메소드를 래핑하여 스레드를 시작할 때마다 pid로 self.pid를 채울 수 있습니까? 자체 스레드 내부에서 os.kill (pid)을 시도했지만 메인을 포함한 모든 스레드를 중지하고 부모가 외부에서 수행해야하지만 부모에서 해당 자식을 어떻게 가져 오는가?
Rodrigo Formighieri

다른 사람들이 암시했듯이, 이것은 슬프게도 32 비트 Arm에서 실행되는 임베디드 리눅스와 같은 것에서는 작동하지 않습니다.
Travis Griggs

@TravisGriggs이 개념은 32 비트 ARM 플랫폼을 포함하여 Linux로 이식 가능합니다. 올바른 시스템 호출 번호를 가져 오기만하면됩니다 (ARM 및 ARM64에서 224 일 수 있음). 작은 C 프로그램으로 빌드 또는 런타임에 확인할 수 있습니다. 이것은 RPi에서 Python 3.7과 함께 작동합니다. Jake Tesler의 대답은 아직 Raspbian 10에없는 Python 3.8을 사용하는 경우 더 좋습니다.
TrentP December


7

다음과 같은 스레드 ID의 예를 보았습니다.

class myThread(threading.Thread):
    def __init__(self, threadID, name, counter):
        self.threadID = threadID
        ...

스레딩 모듈 문서의 목록 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.

7

현재 실행중인 스레드의 ID를 얻을 수 있습니다. 현재 스레드가 종료되면 ID를 다른 스레드에 재사용 할 수 있습니다.

Thread의 인스턴스를 만들 때 이름은 스레드에 암시 적으로 주어지며 패턴은 Thread-number입니다.

이름은 의미가 없으며 고유하지 않아도됩니다. 실행중인 모든 스레드의 ID는 고유합니다.

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 () 함수는 현재 실행중인 스레드를 반환합니다. 이 객체는 스레드의 전체 정보를 보유합니다.


0

파이썬에서 여러 스레드를 만들었고 스레드 개체를 인쇄했으며 ident변수를 사용하여 id를 인쇄했습니다 . 모든 ID가 동일하다는 것을 알았습니다.

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

4
docs.python.org/2/library/threading.html#threading.Thread.identidentThread identifiers may be recycled when a thread exits and another thread is created.
oblalex

0

@brucexin과 마찬가지로 OS 수준 스레드 식별자 (!! 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에 달려 있습니다.


나는 이것이 내가 찾고있는 크로스 플랫폼 버전이되기를 희망했지만 키워드 invalid syntax뒤에 포인터가 extern있습니다. 내가 놓친 것이 있습니까? 코드가 별도의 모듈에 있고 pyx 확장자를 갖는 것이 중요합니까? 아니면 이것이 (재) 컴파일입니까?
트래비스 Griggs

예, 이것은 Cython에 따라 다르며 .pyx파일에 있어야합니다 . "순수한 파이썬"의 경우 아마도 ctypes로 비슷한 것을 할 수 있습니다.
kirr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.