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

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

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

Use la función prctl(2) con la opción PR_SET_NAME (vea los documentos ).

Tenga en cuenta que los documentos son un poco confusos. Ellos dicen

Establezca el nombre del proceso para el proceso de llamada

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

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

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

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

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

o desde info threads GDB entre comillas dobles:

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

A partir de glibc v2.12, puede 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  // or maybe  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  // or  ? // 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 yo sé en Linux , debe ser consistente. Además de Mac OS X (donde solo se puede hacer desde el hilo), los otros son al menos simples de adaptar para código multiplataforma.

Fuentes:

  • glibc NEWS (menciona nuevas interfaces en 2.12)
  • glibc nptl / ChangeLog (menciona nuevas interfaces en 2.12)
  • MKS setname / getname
  • IBM setname / getname
  • Mac OS X de /Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
  • QNX setname / getname
  • FreeBSD setname / no getname por lo que puedo ver
  • OpenBSD setname / no getname por lo que puedo ver
  • NetBSD setname / getname

Puede implementar esto usted mismo al crear 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, necesitará usar un mutex u otra primitiva de sincronización para evitar que varios hilos modifiquen simultáneamente el diccionario (a menos que la 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 hilos si lo hace (mientras que, con un diccionario, puede iterar sobre todos los pares de identificación / nombre de subproceso de cualquier subproceso).