How to set the name of a thread in Linux pthreads?
Solution 1:
As of glibc v2.12, you can use pthread_setname_np
and pthread_getname_np
to set/get the thread name.
These interfaces are available on a few other POSIX systems (BSD, QNX, Mac) in various slightly different forms.
Setting the name will be something like this:
#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*);
And you can get the name back:
#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);
As you can see it's not completely portable between POSIX systems, but as far as I can tell across linux it should be consistent. Apart from Mac OS X (where you can only do it from within the thread), the others are at least simple to adapt for cross-platform code.
Sources:
- glibc NEWS (mentions new interfaces in 2.12)
- glibc nptl/ChangeLog (mentions new interfaces in 2.12)
- MKS setname / getname
- IBM setname / getname
- Mac OS X from
/Developer/SDKs/MacOSX10.7.sdk/usr/include/pthread.h
- QNX setname / getname
- FreeBSD setname / no getname as far as i can see
- OpenBSD setname / no getname as far as i can see
- NetBSD setname / getname
Solution 2:
Use the prctl(2)
function with the option PR_SET_NAME
(see the docs).
Note that old versions of the docs are a bit confusing. They say
Set the process name for the calling process
but since threads are light weight processes (LWP) on Linux, one thread is one process in this case.
You can see the thread name with ps -o cmd
or with:
cat /proc/$PID/task/$TID/comm
or in between the ()
of cat /proc/$PID/task/$TID/stat
:
4223 (kjournald) S 1 1 1 0...
or from GDB info threads
between double quotes:
* 1 Thread 0x7ffff7fc7700 (LWP 6575) "kjournald" 0x00007ffff78bc30d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
Solution 3:
You can implement this yourself by creating a dictionary mapping pthread_t
to std::string
, and then associate the result of pthread_self() with the name that you want to assign to the current thread. Note that, if you do that, you will need to use a mutex or other synchronization primitive to prevent multiple threads from concurrently modifying the dictionary (unless your dictionary implementation already does this for you). You could also use thread-specific variables (see pthread_key_create, pthread_setspecific, pthread_getspecific, and pthread_key_delete) in order to save the name of the current thread; however, you won't be able to access the names of other threads if you do that (whereas, with a dictionary, you can iterate over all thread id/name pairs from any thread).