Pythonスレッドの名前を設定すると、htopまたはpsに表示されません。ps出力には、スレッド名としてpython
のみが表示されます。方法はありますか?それらのようなシステムレポートに表示されるようにスレッド名を設定するには?
from threading import Thread
import time
def sleeper():
while True:
time.sleep(10)
print "sleeping"
t = Thread(target=sleeper, name="Sleeper01")
t.start()
t.join()
ps -T -p {PID}の出力
PID SPID TTY TIME CMD
31420 31420 pts/30 00:00:00 python
31420 31421 pts/30 00:00:00 python
最初に prctl module をインストールします。 (debian/ubuntuでは、単にSudo apt-get install python-prctl
)
from threading import Thread
import time
import prctl
def sleeper():
prctl.set_name("sleeping tiger")
while True:
time.sleep(10)
print "sleeping"
t = Thread(target=sleeper, name="Sleeper01")
t.start()
t.join()
これはプリント
$ ps -T
PID SPID TTY TIME CMD
22684 22684 pts/29 00:00:00 bash
23302 23302 pts/29 00:00:00 python
23302 23303 pts/29 00:00:00 sleeping tiger
23304 23304 pts/29 00:00:00 ps
prctl
がシステムにインストールされている場合、次のモンキーパッチを使用してpythonスレッドの名前をシステムに伝播します。
try:
import prctl
def set_thread_name(name): prctl.set_name(name)
def _thread_name_hack(self):
set_thread_name(self.name)
threading.Thread.__bootstrap_original__(self)
threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap
threading.Thread._Thread__bootstrap = _thread_name_hack
except ImportError:
log('WARN: prctl module is not installed. You will not be able to see thread names')
def set_thread_name(name): pass
このコードの実行後、通常どおりスレッドの名前を設定できます。
threading.Thread(target=some_target, name='Change monitor', ...)
つまり、すでにスレッドの名前を設定している場合は、何も変更する必要はありません。これが100%安全であるとは保証できませんが、私には有効です。
Prctlモジュールは素敵で多くの機能を提供しますが、libcap-devパッケージに依存しています。 Libcap2は、多くのパッケージ(systemdなど)の依存関係であるため、インストールされる可能性が高いです。したがって、設定されたスレッド名のみが必要な場合は、ctypesではなくlibcap2を使用します。
以下の改善された悲嘆の回答を参照してください。
LIB = 'libcap.so.2'
try:
libcap = ctypes.CDLL(LIB)
except OSError:
print(
'Library {} not found. Unable to set thread name.'.format(LIB)
)
else:
def _name_hack(self):
# PR_SET_NAME = 15
libcap.prctl(15, self.name.encode())
threading.Thread._bootstrap_original(self)
threading.Thread._bootstrap_original = threading.Thread._bootstrap
threading.Thread._bootstrap = _name_hack
代替ソリューション(スレッド名ではなくプロセス名を設定するため、実際にはダーティなソリューション)は、pypiのsetproctitle
モジュールを使用することです。
pip install setproctitle
を使用してインストールし、次のように使用できます。
import setproctitle
import threading
import time
def a_loop():
setproctitle.setproctitle(threading.currentThread().name)
# you can otherwise explicitly declare the name:
# setproctitle.setproctitle("A loop")
while True:
print("Looping")
time.sleep(99)
t = threading.Thread(target=a_loop, name="ExampleLoopThread")
t.start()