¿Cómo establecer el nombre de un hilo en Linux pthreads?

7 minutos de lectura

avatar de usuario
Seudónimo

¿Hay alguna forma de establecer el nombre de un hilo en Linux?

Mi objetivo principal es que sería útil durante la depuración, y también sería bueno si ese nombre se expusiera, por ejemplo, a través de /proc/$PID/task/$TID/...

  • ¿Podría decirme, posiblemente con algunos ejemplos, cómo los nombres pueden ser útiles en la depuración?

    usuario184968

    3 de marzo de 2010 a las 8:42

  • @skwllsp: ¿Para que pueda identificar más fácilmente el hilo?

    – Aarón Digulla

    3 de marzo de 2010 a las 8:45

  • Los nombres de los subprocesos definitivamente ayudan cuando tiene programas con un gran conjunto de subprocesos diferentes, cada uno de los cuales hace algo específico (como una configuración de tubería donde cada subproceso realiza una parte de una tarea de procesamiento para cada paquete). He visto la necesidad de esto. Las buenas herramientas de depuración con conocimiento del sistema operativo también deberían poder mostrar estos nombres, no está claro cuántos de los depuradores que existen hoy en día lo hacen.

    – jakobengblom2

    22 de noviembre de 2010 a las 11:34

  • Duplicado de stackoverflow.com/questions/778085/…

    – usuario9876

    19 mayo 2011 a las 14:53

  • Posiblemente una mejor solución ya que las funciones predeterminadas no reflejan el nombre en el /proc/self/comm archivo del hilo. O duplica el conjunto de apellidos, que es tan inútil como no tenerlo. Se permite escribir directamente en el archivo comm y funciona como se esperaba para todas las herramientas (como htop y ps).

    – Alexis Wilke

    6 ago 2021 a las 21:04

avatar de usuario
drfrogsplat

A partir de glibc v2.12, puede utilizar pthread_setname_np y pthread_getname_np para establecer/obtener el nombre del hilo.

Estas interfaces están disponibles en algunos otros sistemas POSIX (BSD, QNX, Mac) en varias formas ligeramente diferentes.

Establecer el nombre será algo como esto:

#include <pthread.h>  // or maybe <pthread_np.h> for some OSes

// Linux
int pthread_setname_np(pthread_t thread, const char *name);

// NetBSD: name + arg work like printf(name, arg)
int pthread_setname_np(pthread_t thread, const char *name, void *arg);

// FreeBSD & OpenBSD: function name is slightly different, and has no return value
void pthread_set_name_np(pthread_t tid, const char *name);

// Mac OS X: must be set from within the thread (can't specify thread ID)
int pthread_setname_np(const char*);

Y puedes recuperar el nombre:

#include <pthread.h>  // or <pthread_np.h> ?

// Linux, NetBSD:
int pthread_getname_np(pthread_t th, char *buf, size_t len);
// some implementations don't have a safe buffer (see MKS/IBM below)
int pthread_getname_np(pthread_t thread, const char **name);
int pthread_getname_np(pthread_t thread, char *name);

// FreeBSD & OpenBSD: dont' seem to have getname/get_name equivalent?
// but I'd imagine there's some other mechanism to read it directly for say gdb

// Mac OS X:
int pthread_getname_np(pthread_t, char*, size_t);

Como puede ver, no es completamente portátil entre los sistemas POSIX, pero por lo que puedo ver en linux debe ser consistente. Aparte de Mac OS X (donde solo puede hacerlo desde dentro del hilo), los otros son al menos fáciles de adaptar para el código multiplataforma.

Fuentes:

  • No entiendo cuál es el punto de pthread_set_name_np() está en BSD si no se puede recuperar el nombre…?

    – Kralyk

    28 de enero de 2015 a las 15:16

  • @kralyk, sí, no es tan útil para el uso en la aplicación, pero sospecho que se puede recuperar a través de algún otro mecanismo (por ejemplo, ¿leer de la memoria directamente por gdb o algo así?)… FWIW NetBSD es compatible con las interfaces de Linux (y los extiende ligeramente con un uso similar a printf)

    – drfrogsplat

    30 de enero de 2015 a las 1:10

  • @drfrogsplat: ¿dónde está una constante que define la longitud máxima del nombre? no veo ningun documento al respecto

    – HEKTO

    30 de junio de 2015 a las 21:26

  • @kralyk Creo que será útil durante la depuración con gdb o en top -H

    – Thirupathi Thangavel

    22 de mayo de 2017 a las 7:48

avatar de usuario
Aarón Digulla

Utilizar el prctl(2) función con la opción PR_SET_NAME (ver los documentos).

Tenga en cuenta que las versiones anteriores de los documentos son un poco confusas. Ellos dicen

Establecer el nombre del proceso para el proceso de llamada

pero dado que los subprocesos son procesos ligeros (LWP) en Linux, un subproceso es un proceso en este caso.

Puedes ver el nombre del hilo con ps -o cmd o con:

cat /proc/$PID/task/$TID/comm

o entre los () de cat /proc/$PID/task/$TID/stat:

4223 (kjournald) S 1 1 1 0...

o del BGF info threads entre comillas dobles:

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  

  • Tenga en cuenta que los nombres reales de los subprocesos estarán en /proc/$PID/tasks/$TID/stat

    – nos

    3 de marzo de 2010 a las 9:58

  • @nos Aunque no están visibles en la lista del directorio de /proclos hilos son accesibles a través de /proc/$TID (por ser lo mismo que los procesos, básicamente).

    – efímero

    9 de abril de 2012 a las 4:16

  • @nos, al menos en la versión 3.2.0 del kernel, es /proc/$PID/task/$TID/stat (sin s en tareas)

    – Andrés Wagner

    6 de noviembre de 2013 a las 16:54

  • Lo dejaré aquí para completar, posible peligro al cambiar el nombre del hilo principal: Lists.linuxfoundation.org/pipermail/bugme-new/2008-octubre/…

    – bobah

    19 de enero de 2016 a las 16:51

  • @AndrewWagner Aunque los hilos no se enumeran en una lista de directorio de /proc/si accedes /proc/$TID/ todavía puede obtener la información del hilo.

    –Craig McQueen

    25 de mayo de 2016 a las 5:10

avatar de usuario
Michael Aarón Safian

Puede implementar esto usted mismo creando un mapeo de diccionario pthread_t para std::stringy luego asociar el resultado de pthread_self() con el nombre que desea asignar al hilo actual. Tenga en cuenta que, si hace eso, necesitará usar un mutex u otra primitiva de sincronización para evitar que varios subprocesos modifiquen el diccionario al mismo tiempo (a menos que la implementación de su diccionario ya lo haga por usted). También puede usar variables específicas de subprocesos (ver pthread_key_create, pthread_setespecífico, pthread_getspecificy pthread_key_delete) para guardar el nombre del hilo actual; sin embargo, no podrá acceder a los nombres de otros subprocesos si lo hace (mientras que, con un diccionario, puede iterar sobre todos los pares de ID/nombre de subprocesos de cualquier subproceso).

  • Tenga en cuenta que esta solución es portátil en Linux, Mac OS X y todos los sistemas que cumplen con la especificación UNIX única. (Una sugerencia publicada por Aaron Digulla para usar “prctl” no es portátil).

    – Michael Aarón Safyan

    3 de marzo de 2010 a las 9:16

  • Esto parece una muy mala idea, y la gente no debería hacerlo.

    – Matt Carpintero

    8 de julio de 2011 a las 4:03

  • ¿Y cómo se puede ver desde fuera de la APP? como en ps, o superior?

    – elcuco

    26 de diciembre de 2011 a las 10:22

  • Este comentario estaba un poco desactualizado. La respuesta de dfrogsplat es la mejor, dado que ahora es compatible con todas las plataformas.

    – Michael Aarón Safyan

    9 de enero de 2012 a las 23:47

  • +1: sigue siendo útil en Linux integrado con bibliotecas C obsoletas o exóticas.

    – FooF

    11 de julio de 2013 a las 9:08

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad