2010-03-03 3 views
53

Gibt es eine Möglichkeit, den Namen eines Threads in Linux festzulegen?Kann ich den Namen eines Threads in Pthreads/Linux setzen?

Mein Hauptzweck ist es wäre hilfreich beim Debuggen, und auch schön, wenn dieser Name z. /proc/$PID/task/$TID/...

+1

Könnten Sie bitte vielleicht mit einigen Beispielen erklären, wie Namen beim Debuggen nützlich sein können? –

+5

@skwllsp: So können Sie den Thread leichter identifizieren? –

+1

Threads-Namen helfen definitiv, wenn Sie Programme mit einer großen Menge verschiedener Threads haben, die jeweils etwas Spezielles tun (wie ein Pipeline-Setup, bei dem jeder Thread einen Teil einer Verarbeitungsaufgabe für jedes Paket ausführt). Ich habe die Notwendigkeit dafür gesehen. Gute Debug-Tools mit Betriebssystem-Kenntnissen sollten auch in der Lage sein, diese Namen anzuzeigen, und nicht, wie viele Debugger es heute machen. – jakobengblom2

Antwort

25

Verwenden Sie die Funktion prctl(2) mit der Option PR_SET_NAME (siehe the docs).

Beachten Sie, dass die Dokumente ein wenig verwirrend sind. Sie sagen

den Namen Prozess Set für den anrufenden Prozess

aber da Fäden Leichtgewichtler Prozesse (LWP) auf Linux sind, ein Thread ist ein Prozess in diesem Fall.

Sie können den Thread-Namen mit ps -o cmd oder in /proc/$PID/stat zwischen dem siehe ():

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

Beachten Sie, dass die tatsächlichen Thread-Namen in/proc/$ PID/tasks/$ TID/stat sind – nos

+0

@nos Auch wenn sie in der Verzeichnisliste von '/ proc' nicht sichtbar sind, sind die Threads über '/ proc/$ TID' zugänglich (da sie im Prinzip die gleichen sind wie Prozesse). – ephemient

+1

@nos, zumindest in Kernel-Version 3.2.0, es ist '/ proc/$ PID/Aufgabe/$ TID/stat' (keine s auf Aufgaben) –

5

du dir pthread_t-std::string, und ordnen Sie dann das Ergebnis der pthread_self() mit dem Namen, indem Sie ein Wörterbuch-Mapping implementieren dass Sie dem aktuellen Thread zuweisen möchten. Beachten Sie, dass Sie in diesem Fall ein Mutex- oder anderes Synchronisierungsgrundelement verwenden müssen, um zu verhindern, dass mehrere Threads gleichzeitig das Wörterbuch ändern (es sei denn, Ihre Wörterbuchimplementierung tut dies bereits für Sie). Sie können 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 Dictionary über alle Thread-ID/Name-Paare aus einem beliebigen Thread iterieren können).

+3

Beachten Sie, dass diese Lösung unter Linux, Mac OS X und allen Systemen, die der Single UNIX Specification entsprechen, portierbar ist. (Ein Vorschlag von Aaron Digulla, "prctl" zu verwenden, ist nicht übertragbar). –

+2

Das scheint eine wirklich schlechte Idee zu sein, und die Leute sollten es nicht tun. –

+2

Und wie können Sie es von außerhalb der APP sehen? wie in PS, oder oben? – elcuco

89

Ab glibc v2.12 können Sie pthread_setname_np und pthread_getname_np verwenden, um den Thread-Namen festzulegen/abzurufen.

Diese Schnittstellen sind auf einigen anderen POSIX-Systemen (BSD, QNX, Mac) in verschiedenen leicht unterschiedlichen Formen verfügbar.

den Namen Einstellung wird so etwas wie dieses:

#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ück:

#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 es sehen können, nicht vollständig portabel zwischen POSIX-Systemen, aber so weit wie ich über Linux sagen kann, sollte es konsistent sein. Abgesehen von Mac OS X (wo es nur innerhalb des Threads möglich ist), sind die anderen zumindest einfach für plattformübergreifenden Code anzupassen.

Quellen:

+0

Ich verstehe nicht, was der Punkt von 'Pthread_set_name_np()' auf BSD ist, wenn der Name nicht abgerufen werden kann ...? – kralyk

+0

@kralyk, ja es ist nicht so nützlich für In-App-Verwendung, aber ich vermute, dass es durch einen anderen Mechanismus abgerufen werden kann (z. B. aus dem Speicher direkt von gdb oder etwas lesen?) ... FWIW NetBSD ist kompatibel mit den Linux-Schnittstellen (und dehnt sie leicht mit printf-like Verwendung aus) – drfrogsplat

+0

@drfrogsplat - Wo ist eine Konstante und definiert die maximale Länge des Namens? Ich sehe keine Dokumente darüber – HEKTO