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


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

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

3 answers

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

Tenga en cuenta que los documentos son un poco confusos. Dicen

Establece el nombre del proceso para el proceso que llama

Pero como 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 el () de cat /proc/$PID/task/$TID/stat:

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

O desde GDB info threads entre doble citas:

* 1    Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84                                                                                  
 27
Author: Aaron Digulla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 13:06:50

A partir de glibc v2.12, puedes usar 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 puedes ver no es completamente portable entre sistemas POSIX, pero por lo que puedo decir a través de linux debería ser consistente. Aparte de Mac OS X (donde solo puedes hacerlo desde dentro del subproceso), los otros son al menos fáciles de adaptar para código multiplataforma.

Fuentes:

 91
Author: drfrogsplat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-30 01:08:17

Puede implementar esto usted mismo creando una asignación de diccionario pthread_t a std::string, y luego asociar el resultado de pthread_self() con el nombre que desea asignar al hilo actual. Tenga en cuenta que, si lo hace, tendrá que usar un mutex u otra primitiva de sincronización para evitar que varios subprocesos modifiquen simultáneamente el diccionario (a menos que su implementación del diccionario ya lo haga por usted). También puede usar variables específicas de subprocesos (consulte pthread_key_create, pthread_setspecific, pthread_getspecific , y pthread_key_delete) para guardar el nombre del subproceso 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 id/nombre de subproceso de cualquier subproceso).

 5
Author: Michael Aaron Safyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-03 09:49:17