64 votes

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

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

Mon objectif principal est d'être utile lors du débogage, et c'est également bien si ce nom est exposé par le biais, par exemple, de l'outil de débogage. /proc/$PID/task/$TID/...

1 votes

Pourriez-vous éventuellement expliquer à l'aide d'exemples comment les noms peuvent être utiles au débogage ?

9 votes

@skwllsp : Pour que vous puissiez identifier plus facilement le fil de discussion ?

2 votes

Les noms de threads sont très utiles lorsque vous avez des programmes avec un grand nombre de threads différents, chacun faisant quelque chose de spécifique (comme une configuration de pipeline où chaque thread effectue une partie d'une tâche de traitement pour chaque paquet). J'en ai vu la nécessité. De bons outils de débogage avec conscience du système d'exploitation devraient également être capables d'afficher ces noms, mais je ne sais pas exactement combien de débogueurs le font aujourd'hui.

123voto

drfrogsplat Points 1220

À partir de la glibc v2.12, vous pouvez utiliser pthread_setname_np y 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.

La définition du 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, il n'est pas complètement portable entre les systèmes POSIX, mais pour autant que je puisse dire à travers linux il doit être cohérent. À l'exception de Mac OS X (où vous ne pouvez le faire qu'à partir du fil de discussion), les autres sont au moins simples à adapter pour le code multiplateforme.

Fuentes:

0 votes

Je ne comprends pas quel est le but de pthread_set_name_np() est sur BSD si le nom ne peut être retrouvé... ?

0 votes

@kralyk, ouais, ce n'est pas très utile pour l'utilisation dans l'application, mais je soupçonne qu'il peut être récupéré par un autre mécanisme (par exemple, lu de la mémoire directement par gdb ou quelque chose comme ça ?) Pour info, NetBSD est compatible avec les interfaces Linux (et les étend légèrement avec une utilisation de type printf).

0 votes

@drfrogsplat - Où se trouve une constante, définissant la longueur maximale du nom ? Je ne vois pas de documentation à ce sujet.

37voto

Aaron Digulla Points 143830

Utilisez le prctl(2) avec l'option PR_SET_NAME (voir les docs ).

Notez que les anciennes versions de la documentation sont un peu confuses. Elles disent

Définir le nom du 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 à partir de GDB info threads entre guillemets :

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

3 votes

Notez que les noms de threads réels seront dans /proc/$PID/tasks/$TID/stat.

0 votes

@nos Même s'ils ne sont pas visibles dans la liste de l'annuaire de /proc les fils sont accessibles via /proc/$TID (parce qu'ils sont identiques aux processus, en fait).

1 votes

@nos, au moins dans la version du noyau 3.2.0, c'est /proc/$PID/task/$TID/stat (pas de s sur les tâches)

6voto

Michael Aaron Safyan Points 45071

Vous pouvez l'implémenter vous-même en créant un mapping de dictionnaire pthread_t a std::string puis associe le résultat de pthread_self() avec le nom que vous voulez attribuer au fil 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 l'implémentation de votre dictionnaire ne le fasse déjà pour vous). Vous pouvez également utiliser des variables spécifiques aux threads (voir pthread_key_create , pthread_setspecific , pthread_getspecific y 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 faites cela (alors qu'avec un dictionnaire, vous pouvez itérer sur toutes les paires id/nom de n'importe quel thread).

3 votes

Notez que cette solution est portable sur Linux, Mac OS X et tous les systèmes conformes à la spécification UNIX unique. (Une suggestion postée par Aaron Digulla d'utiliser "prctl" n'est pas portable).

2 votes

Cela semble être une très mauvaise idée, et les gens ne devraient pas le faire.

3 votes

Et comment pouvez-vous le voir de l'extérieur de l'APP ? comme dans ps, ou top ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X