Когда я устанавливаю имя для потока 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
4 ответа
Сначала установите модуль prctl. (В 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
Я использую следующий патч обезьяны для распространения имени Python Thread в системе, если prctl
установлен в системе:
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% безопасно, но это работает для меня.
Альтернативное решение (на самом деле грязное, поскольку оно устанавливает имя процесса, а не имя потока) состоит в использовании модуля setproctitle
из pypi.
Вы можете установить его с помощью 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()
Модуль 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
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.