Python 线程名称未显示在 ps 或 htop 上
Python thread name doesn't show up on ps or 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
首先安装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
注意:python3 用户可能希望使用 pyprctl。
如果系统中安装了 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)的依赖项。因此,如果您只需要设置线程名称,请使用 libcap2 而不是 ctypes。
请参阅下面改进的 Grief 答案。
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()
我找到了一个工具--py-spy来显示python线程而运行.
,我很困惑
安装:pip3 install -i https://pypi.doubanio.com/simple/ py-spy
用法:py-spy dump --pid 进程号
例如py-spy dump --pid 1234 可以显示python进程1234
的所有线程栈,名称,id
当我为 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
注意:python3 用户可能希望使用 pyprctl。
如果系统中安装了 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)的依赖项。因此,如果您只需要设置线程名称,请使用 libcap2 而不是 ctypes。
请参阅下面改进的 Grief 答案。
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()
我找到了一个工具--py-spy来显示python线程而运行.
,我很困惑安装:pip3 install -i https://pypi.doubanio.com/simple/ py-spy
用法:py-spy dump --pid 进程号
例如py-spy dump --pid 1234 可以显示python进程1234
的所有线程栈,名称,id