web-dev-qa-db-fra.com

Comment définir le nom d'un thread dans les pthreads Linux?

Existe-t-il un moyen de définir le nom d'un thread sous Linux?

Mon objectif principal est qu'il serait utile lors du débogage, et aussi agréable si ce nom était exposé par exemple. /proc/$PID/task/$TID/...

57
Anonym

Utilisez la fonction prctl(2) avec l'option PR_SET_NAME (voir la documentation ).

Notez que les documents sont un peu déroutants. Ils disent

Définissez le nom du processus pour le processus appelant

mais comme les threads sont des processus légers (LWP) sous Linux, un thread est un processus dans ce cas.

Vous pouvez voir le nom du fil avec ps -o cmd ou avec:

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

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

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

ou de GDB info threads entre guillemets:

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

Depuis la glibc v2.12, vous pouvez utiliser pthread_setname_np et pthread_getname_np pour définir/obtenir le nom du thread.

Ces interfaces sont disponibles sur quelques autres systèmes POSIX (BSD, QNX, Mac) sous différentes formes légèrement différentes.

Définir le nom sera quelque chose comme ceci:

#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*);

Et vous pouvez récupérer le nom:

#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);

Comme vous pouvez le voir, ce n'est pas complètement portable entre les systèmes POSIX, mais pour autant que je sache linux , il devrait être cohérent. Mis à part Mac OS X (où vous ne pouvez le faire que depuis le fil), les autres sont au moins simples à adapter pour le code multiplateforme.

Sources:

102
drfrogsplat

Vous pouvez l'implémenter vous-même en créant un mappage de dictionnaire pthread_t à std::string, puis associez le résultat de pthread_self () au nom que vous souhaitez attribuer au thread actuel. Notez que, si vous le faites, vous devrez utiliser un mutex ou une autre primitive de synchronisation pour empêcher plusieurs threads de modifier simultanément le dictionnaire (sauf si votre implémentation de dictionnaire le fait déjà pour vous). Vous pouvez également utiliser des variables spécifiques au thread (voir pthread_key_create , pthread_setspecific , pthread_getspecific , et pthread_key_delete ) pour enregistrez le nom du thread actuel; cependant, vous ne pourrez pas accéder aux noms des autres threads si vous le faites (alors qu'avec un dictionnaire, vous pouvez parcourir toutes les paires id/nom de thread à partir de n'importe quel thread).

6