Python'da bir iş parçacığı kimliği nasıl bulunur


179

Çok iş parçacıklı bir Python programı ve bir yardımcı program işlevi var, writeLog(message) izleyen bir zaman damgası iletiyi izleyen . Ne yazık ki, sonuç günlük dosyası hangi iş parçacığının hangi iletiyi oluşturduğuna dair hiçbir belirti vermez.

writeLog()Hangi iş parçacığı çağırıyor tanımlamak için iletiye bir şey eklemek mümkün olmak istiyorum . Açıkçası ben sadece iş parçacığı bu bilgileri aktarmak yapmak, ama bu çok daha fazla iş olurdu. os.getpid()Kullanabileceğim bir iplik eşdeğeri var mı ?

Yanıtlar:


227

threading.get_ident()çalışır veya threading.current_thread().ident(veya threading.currentThread().identPython <2.6 için).


3
Bağlantılarınız düzeltildi Nicholas. Kısa süre önce, dokümanlardaki bir başlığın üzerine gelirseniz sağda küçük bir kırmızı simge göründüğünü fark ettim. Dokümanlara daha spesifik bağlantılar için kopyalayın + yapıştırın :-)
Jon Cage

2
Jython kullanıyorsanız, threading.currentThread()2.5 sürümünden sonra (camel_ase değil, camelCase değil) istediğinizi unutmayın.
Cam Jackson

3
@CharlesAnderson dikkat edin, Thread.name üzerindeki python dokümanlar "name - Yalnızca tanımlama amacıyla kullanılan bir dize. Semantik içermiyor. Birden çok iş parçacığına aynı ad verilebilir. İlk ad yapıcı tarafından belirlenir."
drevicko

7
Ayrıca, en azından OS X'teki Python 2.5 ve 2.6'da threading.current_thread().ident, uygun olmayan bir hata var gibi görünüyor None. Muhtemelen sadece thread.get_ident()Python 2 ve threading.current_thread().identPython 3'te kullanmak mantıklıdır
Nicholas Riley

5
Cevabım önceki sürümleri did söz thread.get_ident()( threading.get_ident()- belgelere bağlantıları takip Python 3.3 eklenmiştir).
Nicholas Riley

68

Günlük modülünü kullanarak, geçerli günlük tanımlayıcısını her günlük girişine otomatik olarak ekleyebilirsiniz. Logger format dizenizde şu LogRecord eşleme anahtarlarından birini kullanmanız yeterlidir :

% (thread) d: Konu kimliği (varsa).

% (threadName) s: Konu adı (varsa).

ve varsayılan işleyicinizi onunla ayarlayın:

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

Logger kullanıyorum. Bu yüzden cevap verdiğinizin en basit çözüm olduğunu düşünüyorum. Ama bunu <concurrent.futures.thread.ThreadPoolExecutor object at 0x7f00f882a438>_2 bir iş parçacığı adı olarak alıyorum . İki çağrılan benim iplik numarası olduğunu mı
Ravi Shankar Reddy

22

thread.get_ident()Fonksiyon Linux üzerinde uzun bir tamsayı döndürür. Gerçekten bir iş parçacığı kimliği değil.

Kullandığım bu yöntemi gerçekten Linux üzerinde iplik id almak için:

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)

Bu bazen kullanılabilir, ancak taşınabilir değildir
Piyush Kansal

3
Bu yanıtı düzenleyebilir misiniz, böylece bağlantı kötüleşirse ziyaretçiler için faydalı olmaya devam eder mi?
josliber

Benim iplik sınıfının start () yöntemini nasıl sarın böylece iplik her başlattığımda kendi pid ile kendi pid doldurabilirsiniz? Kendi dişinin içinden os.kill (pid) denedim, sadece ana da dahil olmak üzere tüm konuları durdurur, harici olarak ebeveyn tarafından yapılmalıdır, ancak bu çocuk ebeveynten nasıl alınır?
Rodrigo Formighieri

Diğerlerinin ima ettiği gibi, bu ne yazık ki 32 bit kolda çalışan gömülü bir linux gibi bir şey üzerinde çalışmaz.
Travis Griggs

@TravisGriggs Konsept 32 bit ARM platformları dahil olmak üzere Linux için taşınabilir. Sadece ARM ve ARM64'te 224 olacak doğru sistem çağrı numarasını almanız gerekir. Küçük bir C programı ile derleme veya çalışma zamanında belirlenebilir. Bu benim için RPi üzerinde Python 3.7 ile çalışıyor. Jake Tesler'in cevabı, Raspbian 10'da henüz mevcut olmayan Python 3.8'e sahipseniz daha iyidir.
TrentP


7

Bunun gibi iş parçacığı kimlikleri örnekleri gördüm:

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

İş parçacığı modülü belgeleriname de özniteliği listeler :

...

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

Mevcut çalışan iş parçacığının kimliğini alabilirsiniz. Geçerli iş parçacığı biterse, kimlik diğer iş parçacıkları için yeniden kullanılabilir.

Bir İş Parçacığı örneğini sandığınızda, iş parçacığına örtük bir desen verilir;

Adın bir anlamı yoktur ve adın benzersiz olması gerekmez. Çalışan tüm iş parçacıklarının kimliği benzersizdir.

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 () işlevi, geçerli çalışan iş parçacığını döndürür. Bu nesne, iş parçacığının tüm bilgilerini tutar.


0

Python'da birden çok iş parçacığı oluşturdum, iş parçacığı nesnelerini yazdırdım ve identdeğişkeni kullanarak kimliği yazdırdım . Tüm kimlikleri aynı görüyorum:

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

4
Bunun için docs gibi geri dönüşümlü sanırım ident: söz hakkından 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'e benzer şekilde, OS düzeyinde iş parçacığı tanımlayıcısı (ki! = thread.get_ident()) Almak ve belirli sayılara bağlı olmamak ve sadece amd64 olmak için aşağıdaki gibi bir şey kullanmak gerekiyordu:

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

ve

---- 8< ---- (test.py)
import pyximport; pyximport.install()
import xos

...

print 'my tid: %d' % xos.gettid()

bu Cython'a bağlı.


Bu aradığım çapraz platform versiyonu olacağını umuyordum, ama bu konuda bir hata alıyorum, anahtar kelime invalid syntaxsonrası işaretçi extern. Kaçırdığım bir şey var mı? Kodun ayrı bir modülde olması ve pyx uzantısına sahip olması önemli mi? Yoksa bu (yeniden) derlenen bir şey midir?
Travis Griggs

Evet, bu Cython'a bağlıdır ve bir .pyxdosyada bulunmalıdır . "Saf piton" için muhtemelen benzer bir şey ctypes ile de yapılabilir.
kirr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.