El nombre del hilo de Python no aparece en ps o htop
multithreading (4)
Cuando configuro el nombre de un hilo de Python, no aparece en htop o ps. La salida ps solo muestra python
como el nombre del hilo. ¿Hay alguna forma de establecer un nombre de hilo para que aparezca en los informes del sistema como ellos?
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} salida
PID SPID TTY TIME CMD
31420 31420 pts/30 00:00:00 python
31420 31421 pts/30 00:00:00 python
El módulo Prctl es bueno y proporciona muchas características, pero depende del paquete libcap-dev. Es probable que Libcap2 esté instalado porque es una dependencia de muchos paquetes (systemd, por ejemplo). Entonces, si solo necesitas establecer un nombre de hilo, usa libcap2 sobre ctypes.
Vea la respuesta mejorada de Duelo a continuación.
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
Primero instale el módulo prctl . (En debian / ubuntu solo escriba 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()
Esto imprime
$ 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
Una solución alternativa (en realidad una sucia, ya que establece el nombre del proceso, no el nombre del hilo) es usar el módulo setproctitle de pypi.
Puede instalarlo con pip install setproctitle
y usarlo de la siguiente manera:
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()
Utilizo el siguiente parche de mono para propagar el nombre del hilo de python al sistema si prctl
está instalado en el sistema:
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
Después de la ejecución de este código, puede establecer el nombre del hilo como de costumbre:
threading.Thread(target=some_target, name=''Change monitor'', ...)
Eso significa que, si ya establece nombres para subprocesos, no necesita cambiar nada. No puedo garantizar que esto sea 100% seguro, pero funciona para mí.