पायथन में एक थ्रेड आईडी कैसे खोजें


179

मेरे पास एक बहु-थ्रेडिंग पायथन कार्यक्रम है, और एक उपयोगिता फ़ंक्शन है, writeLog(message)जो संदेश के बाद टाइमस्टैम्प लिखता है। दुर्भाग्य से, परिणामी लॉग फ़ाइल यह संकेत नहीं देती है कि कौन सा धागा किस संदेश को उत्पन्न कर रहा है।

मैं writeLog()संदेश में कुछ जोड़ने में सक्षम होना चाहता हूं ताकि यह पता चल सके कि कौन सा धागा इसे कॉल कर रहा है। जाहिर है कि मैं सिर्फ इस जानकारी में थ्रेड पास कर सकता हूं, लेकिन यह बहुत अधिक काम होगा। वहाँ कुछ धागा है os.getpid()कि मैं का उपयोग कर सकता है?

जवाबों:


227

threading.get_ident()काम करता है, या threading.current_thread().ident(या threading.currentThread().identपायथन <2.6 के लिए)।


3
अपने लिंक निकोलस को ठीक किया। मुझे हाल ही में एहसास हुआ कि यदि आप डॉक्स में एक शीर्षक पर हॉवर करते हैं तो दाईं ओर थोड़ा लाल प्रतीक दिखाई देता है। डॉक्स के अधिक विशिष्ट लिंक के लिए कॉपी + पेस्ट करें :-)
जॉन केज

2
ध्यान दें कि यदि आप Jython का उपयोग कर रहे हैं, तो आप चाहते हैं threading.currentThread()(कैमलकेस, कैमल_केस नहीं) संस्करण 2.5 के रूप में।
कैम जैक्सन

3
@CharlesAnderson beware, पिरथोन डॉक्स ऑन थ्रेड.नाम कहते हैं "नाम - केवल पहचान उद्देश्यों के लिए उपयोग किया जाने वाला एक स्ट्रिंग। इसका कोई शब्दार्थ नहीं है। एकाधिक थ्रेड को एक ही नाम दिया जा सकता है। प्रारंभिक नाम कंस्ट्रक्टर द्वारा निर्धारित किया गया है।"
drevicko

7
यह भी ध्यान दें कि कम से कम पायथन 2.5 और 2.6 ओएस एक्स पर, एक ऐसा बग लगता है जहां threading.current_thread().identअनुचित रूप से है None। शायद समझ में आता है सिर्फ thread.get_ident()पायथन 2 और threading.current_thread().identपायथन 3 में उपयोग करने के लिए
निकोलस रिले

5
मेरे उत्तर के पिछले संस्करणों ने उल्लेख किया थाthread.get_ident() ( threading.get_ident()पायथन 3.3 में जोड़ा गया था - प्रलेखन के लिंक का पालन करें)।
निकोलस रिले

68

लॉगिंग मॉड्यूल का उपयोग करके आप प्रत्येक लॉग प्रविष्टि में वर्तमान थ्रेड पहचानकर्ता को स्वचालित रूप से जोड़ सकते हैं। बस अपने लकड़हारा प्रारूप स्ट्रिंग में इन LogRecord मैपिंग कुंजी में से एक का उपयोग करें:

% (थ्रेड) d: थ्रेड आईडी (यदि उपलब्ध हो)।

% (थ्रेडनाम) s: थ्रेड नाम (यदि उपलब्ध हो)।

और इसके साथ अपना डिफ़ॉल्ट हैंडलर सेट करें:

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

मैं लकड़हारे का उपयोग कर रहा हूं। तो मुझे लगता है कि आप जवाब सबसे सरल उपाय है। लेकिन मुझे <concurrent.futures.thread.ThreadPoolExecutor object at 0x7f00f882a438>_2 यह एक थ्रेड नाम के रूप में मिल रहा है । क्या वह दो मेरे थ्रेड नंबर हैं, जिन्होंने आह्वान किया है
रवि शंकर रेड्डी

22

thread.get_ident()समारोह लिनक्स पर एक लंबे पूर्णांक देता है। यह वास्तव में एक थ्रेड आईडी नहीं है।

मैं वास्तव में लिनक्स पर थ्रेड आईडी प्राप्त करने के लिए इस विधि का उपयोग करता हूं :

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)

यह कभी-कभी उपयोग किया जा सकता है, लेकिन पोर्टेबल नहीं है
पीयूष कांसल

3
क्या आप इस उत्तर को संपादित कर सकते हैं ताकि यह लिंक खराब होने पर आगंतुकों के लिए उपयोगी बना रहे?
josliber

मेरे थ्रेड क्लास की शुरुआत () विधि को कैसे लपेटें ताकि यह मेरे स्वयं को भर सके। यह थ्रेड लॉन्च होने के बाद यह हर बार ख़ुश हो जाता है? खुद के धागे के अंदर से os.kill (pid) की कोशिश की, यह सिर्फ मुख्य सहित सभी धागे को रोकता है, बाहरी रूप से माता-पिता द्वारा किया जाना चाहिए, लेकिन उस बच्चे को माता-पिता से कैसे प्राप्त करना है?
रॉड्रिगो फॉर्मिघिएरी

जैसा कि दूसरों ने संकेत दिया है, यह दुख की बात है कि 32 बिट आर्म पर चलने वाले एम्बेडेड लिनक्स की तरह कुछ काम नहीं करता है।
ट्रैविस ग्रिग्स

@TravisGriggs यह अवधारणा लिनक्स के लिए पोर्टेबल है, जिसमें 32 बिट एआरएम प्लेटफॉर्म शामिल हैं। आपको बस सही सिस्टम कॉल नंबर प्राप्त करने की आवश्यकता है, जो संभवतः एआरएम और एआरएम 64 पर 224 होने जा रहा है। यह एक छोटे सी कार्यक्रम के साथ निर्माण या चलाने के समय पर निर्धारित किया जा सकता है। यह मेरे लिए एक आरपीआई पर पायथन 3.7 के साथ काम करता है। जेक टेस्लर का जवाब बेहतर है अगर आपके पास पायथन 3.8 है, जो कि रास्पियन 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

आप वर्तमान में चल रहे धागे की पहचान प्राप्त कर सकते हैं। यदि वर्तमान थ्रेड समाप्त होता है, तो पहचान को अन्य थ्रेड्स के लिए पुन: उपयोग किया जा सकता है।

जब आप थ्रेड का एक उदाहरण देते हैं, तो थ्रेड को एक नाम दिया जाता है, जो पैटर्न है: थ्रेड-नंबर

नाम का कोई अर्थ नहीं है और नाम का अद्वितीय होना जरूरी नहीं है। सभी चल रहे धागे की पहचान अद्वितीय है।

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()

फ़ंक्शन थ्रेडिंग कर रहा है। Current_thread () वर्तमान रनिंग थ्रेड देता है। यह ऑब्जेक्ट थ्रेड की पूरी जानकारी रखता है।


0

मैंने पायथन में कई थ्रेड्स बनाए, मैंने थ्रेड ऑब्जेक्ट्स मुद्रित किए, और मैंने 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()

यह हालांकि साइथन पर निर्भर करता है।


मुझे उम्मीद थी कि यह क्रॉस प्लेटफॉर्म संस्करण होगा जिसे मैं देख रहा था, लेकिन मुझे इस पर एक त्रुटि मिलती है, कीवर्ड के invalid syntaxबाद पॉइंटर extern। क्या मुझे कुछ याद आ रहा है। क्या यह महत्वपूर्ण है कि कोड एक अलग मॉड्यूल में हो और pyx एक्सटेंशन हो? या यह (पुनः) संकलन बात है?
ट्रैविस ग्रिग्स

हां, यह साइथन पर निर्भर करता है और इसे एक .pyxफाइल में रहना चाहिए । "शुद्ध अजगर" के लिए शायद कुछ ऐसा ही ctypes के साथ भी किया जा सकता है।
सिरप 24'19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.