วิธีค้นหา thread id ใน Python


179

ฉันมีโปรแกรม Python แบบมัลติเธรดและฟังก์ชันยูทิลิตี้writeLog(message)ที่เขียนการประทับเวลาตามด้วยข้อความ น่าเสียดายที่ไฟล์บันทึกผลลัพธ์แสดงว่าไม่มีการระบุว่าเธรดใดกำลังสร้างข้อความใด

ฉันต้องการwriteLog()เพิ่มบางสิ่งบางอย่างในข้อความเพื่อระบุว่าเธรดใดกำลังเรียกใช้ เห็นได้ชัดว่าฉันสามารถทำให้กระทู้ผ่านข้อมูลนี้ แต่นั่นจะทำงานได้มากขึ้น มีเธรดเทียบเท่ากับos.getpid()ที่ฉันสามารถใช้ได้หรือไม่

คำตอบ:


227

threading.get_ident()ทำงานหรือthreading.current_thread().ident(หรือthreading.currentThread().identสำหรับ Python <2.6)


3
แก้ไขลิงค์ของคุณ Nicholas ฉันเพิ่งรู้ว่าถ้าคุณโฮเวอร์เหนือชื่อเรื่องในเอกสารสัญลักษณ์สีแดงเล็ก ๆ ปรากฏขึ้นทางด้านขวา คัดลอก + วางที่สำหรับการเชื่อมโยงที่เฉพาะเจาะจงมากขึ้นในเอกสาร :-)
จอนกรง

2
โปรดทราบว่าหากคุณใช้ Jython คุณต้องการthreading.currentThread()(camelCase ไม่ใช่ camel_case) ในเวอร์ชัน 2.5
Cam Jackson

3
@CharlesAnderson ระวัง python docs ที่Thread.nameพูดว่า "name - สตริงที่ใช้เพื่อระบุตัวตนเท่านั้นไม่มีความหมายเธรดจำนวนมากอาจได้รับชื่อเดียวกันชื่อเริ่มต้นถูกกำหนดโดยนวกรรมิก"
drevicko

7
นอกจากนี้ยังทราบว่าอย่างน้อยในหลาม 2.5 และ 2.6 ใน OS X, ดูเหมือนว่าจะมีข้อผิดพลาดที่เป็นไม่เหมาะสมthreading.current_thread().ident Noneอาจเหมาะสมที่จะใช้thread.get_ident()ใน Python 2 และthreading.current_thread().identPython 3 เท่านั้น
Nicholas Riley

5
คำตอบของฉันในเวอร์ชันก่อนหน้าได้กล่าวถึงแล้วthread.get_ident()( threading.get_ident()เพิ่มใน Python 3.3 - ไปตามลิงก์ไปยังเอกสารประกอบ)
Nicholas Riley

68

การใช้โมดูลการบันทึกคุณสามารถเพิ่มตัวระบุเธรดปัจจุบันในรายการบันทึกแต่ละรายการได้โดยอัตโนมัติ เพียงใช้คีย์การแมปLogRecordหนึ่งในสตริงรูปแบบตัวบันทึกของคุณ:

% (เธรด) d: รหัสเธรด (ถ้ามี)

% (threadName) s: ชื่อเธรด (ถ้ามี)

และตั้งค่าตัวจัดการเริ่มต้นด้วย:

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

ฉันใช้คนตัดไม้ ดังนั้นฉันคิดว่าคุณตอบเป็นทางออกที่ง่ายที่สุด แต่ฉันได้รับ<concurrent.futures.thread.ThreadPoolExecutor object at 0x7f00f882a438>_2 สิ่งนี้เป็นชื่อเธรด นั่นคือสองคือหมายเลขเธรดของฉันที่เรียกใช้
Ravi Shanker Reddy

22

thread.get_ident()ฟังก์ชันส่งกลับจำนวนเต็มยาวบนลินุกซ์ ไม่ใช่รหัสเธรดจริงๆ

ฉันใช้วิธีนี้เพื่อรับ thread id บน 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)

บางครั้งสามารถใช้งานได้ แต่ไม่สามารถพกพาได้
Piyush Kansal

3
คุณช่วยแก้ไขคำตอบนี้ได้ไหมเพื่อที่จะเป็นประโยชน์ต่อผู้เยี่ยมชมหากลิงค์เสีย?
josliber

วิธีการตัดการเริ่มต้น () วิธีการเรียนด้ายของฉันเพื่อให้สามารถเติม self.pid ของฉันด้วยมันเป็น pid ทุกครั้งที่ฉันเปิดด้าย? พยายาม os.kill (pid) จากภายในเธรดของตัวเองมันจะหยุดเธรดทั้งหมดรวมถึงเธรดหลักที่ต้องทำจากภายนอกโดยผู้ปกครอง แต่วิธีการรับ pid เด็กจากผู้ปกครอง?
Rodrigo Formighieri

ดังที่คนอื่น ๆ บอกใบ้เรื่องนี้น่าเศร้าที่ไม่สามารถใช้งานบางอย่างเช่นลินุกซ์ฝังตัวที่ทำงานบนแขน 32 บิต
Travis Griggs

@TravisGriggs แนวคิดนี้สามารถพกพาไปยัง Linux ได้รวมถึงแพลตฟอร์ม ARM 32 บิต คุณเพียงแค่ต้องได้รับหมายเลขโทรศัพท์ระบบที่ถูกต้องซึ่งอาจจะเป็น 224 ใน ARM และ ARM64 มันสามารถถูกกำหนดที่ build หรือรันไทม์ด้วยโปรแกรม C ขนาดเล็ก สิ่งนี้ใช้ได้กับฉันด้วย Python 3.7 บน RPi คำตอบของ Jake Tesler ดีกว่าถ้าคุณมี Python 3.8 ซึ่งยังไม่ปรากฏใน Raspbian 10
TrentP


7

ฉันเห็นตัวอย่างของรหัสประจำเธรดดังนี้:

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

คุณสามารถรับ ident ของเธรดที่กำลังรันอยู่ในปัจจุบัน identifier สามารถใช้ซ้ำสำหรับเธรดอื่นหากเธรดปัจจุบันสิ้นสุด

เมื่อคุณสร้างอินสแตนซ์ของ Thread ชื่อจะถูกกำหนดให้กับเธรดซึ่งเป็นรูปแบบ: Thread-number

ชื่อไม่มีความหมายและชื่อไม่จำเป็นต้องซ้ำกัน ident ของเธรดที่กำลังรันทั้งหมดไม่ซ้ำกัน

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

ฉันสร้างหลายเธรดใน Python ฉันพิมพ์อ็อบเจกต์ thread และพิมพ์ id โดยใช้identตัวแปร ฉันเห็นรหัสทั้งหมดเหมือนกัน:

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

4
ฉันเดาว่ามันจะถูกรีไซเคิลเป็นเอกสารสำหรับการidentพูด: Thread identifiers may be recycled when a thread exits and another thread is created. docs.python.org/2/library/threading.html#threading.Thread.ident
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 หรือไม่ หรือนี่คือสิ่งที่รวบรวมใหม่
Travis Griggs

ใช่ขึ้นอยู่กับ Cython และควรอยู่ใน.pyxไฟล์ สำหรับ "ไพ ธ อนบริสุทธิ์" อาจมีบางสิ่งที่คล้ายกันที่สามารถทำได้ด้วย ctypes เช่นกัน
kirr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.