开发者

How to set the name of a thread in Linux pthreads?

开发者 https://www.devze.com 2022-12-21 15:27 出处:网络
Is there any way of setting the name of a thread in Linux? My ma开发者_JAVA百科in purpose is it would be helpful while debugging, and also nice if that name was exposed through e.g. /proc/$PID/task/$

Is there any way of setting the name of a thread in Linux?

My ma开发者_JAVA百科in purpose is it would be helpful while debugging, and also nice if that name was exposed through e.g. /proc/$PID/task/$TID/...


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


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                                                                                  


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消