マルチスレッドPythonプログラムと、タイムスタンプの後にメッセージが続くユーティリティ関数writeLog(message)
があります。残念ながら、結果のログファイルには、どのスレッドがどのメッセージを生成しているかは示されません。
writeLog()
がメッセージに何かを追加して、どのスレッドがそれを呼び出しているかを識別できるようにしたいと思います。明らかに、スレッドにこの情報を渡すようにすることもできますが、それはさらに多くの作業になります。使用できるos.getpid()
に相当するスレッドはありますか?
threading.get_ident()
動作する、または threading.current_thread().ident
(またはPython <2.6の場合はthreading.currentThread().ident
)。
Linuxでは、thread.get_ident()
関数は長整数を返します。実際にはスレッド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)
このようなスレッドIDの例を見ました:
class myThread(threading.Thread):
def __init__(self, threadID, name, counter):
self.threadID = threadID
...
threading module 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.
現在実行中のスレッドのIDを取得できます。現在のスレッドが終了した場合、identは他のスレッドに再利用できます。
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()は、現在実行中のスレッドを返します。このオブジェクトは、スレッドの情報全体を保持します。
この機能はPython 3.8+でサポートされるようになりました:)
https://github.com/python/cpython/commit/4959c33d2555b89b494c678d99be81a65ee864b
Pythonで複数のスレッドを作成し、スレッドオブジェクトを出力し、ident
変数を使用してIDを出力しました。すべてのIDが同じであることがわかります。
<Thread(Thread-1, stopped 140500807628544)>
<Thread(Thread-2, started 140500807628544)>
<Thread(Thread-3, started 140500807628544)>
@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に依存します。