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 faites cela, vous devrez utiliser un mutex ou une autre primitive de synchronisation pour empêcher plusieurs threads de modifier simultanément le dictionnaire (à moins que votre implémentation de dictionnaire ne le fasse 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) afin de sauvegarder 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 identifiant/nom de thread à partir de n'importe quel thread).
Depuis glibc v2.12, vous pouvez utiliser pthread_setname_np
et pthread_getname_np
pour définir/obtenir le nom du fil.
Ces interfaces sont disponibles sur quelques autres systèmes POSIX (BSD, QNX, Mac) sous diverses formes légèrement différentes.
Définir le nom ressemblera à 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 sur linux ça doit être cohérent. Mis à part Mac OS X (où vous ne pouvez le faire qu'à partir du thread), les autres sont au moins simples à adapter pour le code multiplateforme.
Origine :
- glibc NEWS (mentionne de nouvelles interfaces dans 2.12)
- glibc nptl/ChangeLog (mentionne de nouvelles interfaces dans 2.12)
- MKS setname / getname
- IBM setname / getname
- Mac OS X à partir de
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
- QNX setname / getname
- Setname FreeBSD / pas de getname pour autant que je sache
- Setname OpenBSD / pas de getname pour autant que je sache
- setname / getname NetBSD
Utilisez le prctl(2)
fonction avec l'option PR_SET_NAME
(voir la documentation).
Notez que les anciennes versions de la documentation sont un peu déroutantes. Ils disent
Définir 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 depuis GDB info threads
entre guillemets :
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84