web-dev-qa-db-ja.com

Pythonスレッド名がpsまたはhtopに表示されない

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
27
Chamila

最初に 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
18
Nick Craig-Wood

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%安全であるとは保証できませんが、私には有効です。

7
Grief

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
6
Oleg Golovanov

代替ソリューション(スレッド名ではなくプロセス名を設定するため、実際にはダーティなソリューション)は、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()
0
lanquil