Sie können dies selbst implementieren, indem Sie eine Wörterbuchzuordnung pthread_t
erstellen bis std::string
, und verknüpfen Sie dann das Ergebnis von pthread_self() mit dem Namen, den Sie dem aktuellen Thread zuweisen möchten. Beachten Sie, dass Sie in diesem Fall einen Mutex oder ein anderes Synchronisierungselement verwenden müssen, um zu verhindern, dass mehrere Threads gleichzeitig das Wörterbuch ändern (es sei denn, Ihre Wörterbuchimplementierung erledigt dies bereits für Sie). Sie könnten auch Thread-spezifische Variablen verwenden (siehe pthread_key_create, pthread_setspecific, pthread_getspecific und pthread_key_delete), um den Namen des aktuellen Threads zu speichern; Sie können jedoch nicht auf die Namen anderer Threads zugreifen, wenn Sie dies tun (während Sie mit einem Wörterbuch über alle Thread-ID/Name-Paare von jedem Thread iterieren können).
Ab glibc v2.12 können Sie pthread_setname_np
verwenden und pthread_getname_np
um den Thread-Namen zu setzen/erhalten.
Diese Schnittstellen sind auf einigen anderen POSIX-Systemen (BSD, QNX, Mac) in verschiedenen leicht unterschiedlichen Formen verfügbar.
Das Festlegen des Namens sieht in etwa so aus:
#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*);
Und Sie können den Namen zurückbekommen:
#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);
Wie Sie sehen können, ist es nicht vollständig zwischen POSIX-Systemen portierbar, aber soweit ich das beurteilen kann, über Linux hinweg es sollte konsistent sein. Abgesehen von Mac OS X (wo Sie dies nur innerhalb des Threads tun können), sind die anderen zumindest einfach für plattformübergreifenden Code anzupassen.
Quellen:
- glibc NEWS (erwähnt neue Schnittstellen in 2.12)
- glibc nptl/ChangeLog (erwähnt neue Schnittstellen in 2.12)
- MKS setname / getname
- IBM setname / getname
- Mac OS X ab
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
- QNX setname / getname
- FreeBSD setname / kein getname soweit ich sehen kann
- OpenBSD-Setname / kein Getname, soweit ich sehen kann
- NetBSD-Setname / Getname
Verwenden Sie den prctl(2)
Funktion mit der Option PR_SET_NAME
(siehe Dokumentation).
Beachten Sie, dass alte Versionen der Dokumentation etwas verwirrend sind. Sie sagen
Legen Sie den Prozessnamen für den aufrufenden Prozess fest
aber da Threads unter Linux leichte Prozesse (LWP) sind, ist ein Thread in diesem Fall ein Prozess.
Sie können den Threadnamen mit ps -o cmd
sehen oder mit:
cat /proc/$PID/task/$TID/comm
oder zwischen den ()
von cat /proc/$PID/task/$TID/stat
:
4223 (kjournald) S 1 1 1 0...
oder von GDB info threads
zwischen doppelten Anführungszeichen:
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84