Come impostare il nome di un thread in pthreads Linux?

C’è un modo per impostare il nome di un thread in Linux?

Il mio scopo principale è di essere utile durante il debug, e anche bello se quel nome fosse esposto attraverso ad esempio /proc/$PID/task/$TID/...

Usa la funzione PR_SET_NAME ( prctl(2) con l’opzione PR_SET_NAME (vedi i documenti ).

Nota che i documenti sono un po ‘confusi. Dicono

Imposta il nome del processo per il processo chiamante

ma poiché i thread sono processi leggeri (LWP) su Linux, un thread è un processo in questo caso.

Puoi vedere il nome del thread con ps -o cmd o con:

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

o tra () di cat /proc/$PID/task/$TID/stat :

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

o dai info threads GDB tra virgolette doppie:

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

A partire da glibc v2.12, è ansible utilizzare pthread_setname_np e pthread_getname_np per impostare / ottenere il nome del thread.

Queste interfacce sono disponibili su alcuni altri sistemi POSIX (BSD, QNX, Mac) in varie forms leggermente diverse.

L’impostazione del nome sarà simile a questa:

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

E puoi riavere il nome:

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

Come puoi vedere, non è completamente portatile tra i sistemi POSIX, ma per quanto posso dire su Linux dovrebbe essere coerente. A parte Mac OS X (dove puoi farlo solo all’interno del thread), gli altri sono almeno semplici da adattare per il codice multipiattaforma.

fonti:

  • glibc NEWS (cita le nuove interfacce in 2.12)
  • glibc nptl / ChangeLog (cita le nuove interfacce in 2.12)
  • MKS setname / getname
  • IBM setname / getname
  • Mac OS X da /Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
  • QNX setname / getname
  • FreeBSD setname / no getname per quanto posso vedere
  • OpenBSD setname / no getname per quanto posso vedere
  • NetBSD setname / getname

È ansible implementare questo da soli creando un dizionario mappando pthread_t a std::string , quindi associando il risultato di pthread_self () al nome che si desidera assegnare al thread corrente. Si noti che, se lo si fa, sarà necessario utilizzare un mutex o un’altra primitiva di sincronizzazione per impedire a più thread di modificare simultaneamente il dizionario (a meno che l’implementazione del dizionario lo faccia già per te). Puoi anche utilizzare variabili specifiche del thread (vedi pthread_key_create , pthread_setspecific , pthread_getspecific e pthread_key_delete ) per salvare il nome del thread corrente; tuttavia, non sarà ansible accedere ai nomi di altri thread se lo si fa (mentre, con un dizionario, è ansible scorrere tutte le coppie di id / nome dei thread da qualsiasi thread).