65

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

My main purpose is it would be helpful while debugging, and also nice if that name was exposed through e.g. /proc/$PID/task/$TID/...

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Anonym
  • 677
  • 1
  • 6
  • 5
  • 1
    Could you please tell possibly with some examples how names can be useful in debugging? –  Mar 03 '10 at 08:42
  • 9
    @skwllsp: So you can more easily identify the thread? – Aaron Digulla Mar 03 '10 at 08:45
  • 2
    Threads names definitely help when you have programs with a large set of different threads each doing something specific (like a pipeline setup where each thread does some part of a processing task to each packet). I have seen the need for this. Good debug tools with OS awareness should also be able to display these names, not clear how many of the debuggers out there do that today. – jakobengblom2 Nov 22 '10 at 11:34
  • 1
    Duplicate of http://stackoverflow.com/questions/778085/how-to-name-a-thread-in-linux – user9876 May 19 '11 at 14:53
  • [Possibly a better solution](https://stackoverflow.com/questions/68676407/how-do-i-change-the-name-of-one-single-thread-in-linux/68687132#68687132) as the default functions do not reflect the name in the `/proc/self/comm` file of the thread. Or it duplicates the last name set, which is as useless as not having it. Directly writing to the comm file is allowed and works as expected for a ll tools (such as `htop` and `ps`). – Alexis Wilke Aug 06 '21 at 21:04

3 Answers3

123

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:

drfrogsplat
  • 2,577
  • 3
  • 19
  • 28
  • I don't get what the point of `pthread_set_name_np()` is on BSD if the name cannot be retrieved...? – kralyk Jan 28 '15 at 15:16
  • @kralyk, yeah its not so useful for in-app use, but i suspect it can be retrieved through some other mechanism (e.g. read from memory directly by gdb or something?)... FWIW NetBSD is compatible with the Linux interfaces (and slightly extends them with printf-like usage) – drfrogsplat Jan 30 '15 at 01:10
  • @drfrogsplat - Where is a constant, defining the maximum length of the name? I don't see any docs about it – HEKTO Jun 30 '15 at 21:26
  • 3
    @kralyk I think it'll be useful while debugging with gdb or in `top -H` – Thirupathi Thangavel May 22 '17 at 07:48
38

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                                                                                  
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 3
    Note that the actual thread names will be in /proc/$PID/tasks/$TID/stat – nos Mar 03 '10 at 09:58
  • @nos Even though they're not visible in the directory listing of `/proc`, threads are accessible via `/proc/$TID` (due to being the same as processes, basically). – ephemient Apr 09 '12 at 04:16
  • 1
    @nos, at least in kernel version 3.2.0, it's `/proc/$PID/task/$TID/stat` (no s on tasks) – Andrew Wagner Nov 06 '13 at 16:54
  • 2
    I'll leave it here for completeness, possible pitfall with changing main thread name: https://lists.linuxfoundation.org/pipermail/bugme-new/2008-October/020065.html – bobah Jan 19 '16 at 16:51
  • @AndrewWagner Even though threads are not listed in a directory listing of `/proc/`, if you access `/proc/$TID/` you can still get the thread's information. – Craig McQueen May 25 '16 at 05:10
6

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

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • 3
    Note that this solution is portable across Linux, Mac OS X, and all systems that conform to the Single UNIX Specification. (A suggestion posted by Aaron Digulla to use "prctl" is not portable). – Michael Aaron Safyan Mar 03 '10 at 09:16
  • 2
    This seems like a really bad idea, and people shouldn't do it. – Matt Joiner Jul 08 '11 at 04:03
  • 3
    And how can you see it from outside the APP? like in ps, or top? – elcuco Dec 26 '11 at 10:22
  • This comment was a bit outdated. dfrogsplat's answer is the best one, given that it is now supported across platforms. – Michael Aaron Safyan Jan 09 '12 at 23:47
  • +1 - still useful in embedded Linux with obsolete or exotic C libraries. – FooF Jul 11 '13 at 09:08
  • 1
    In C, you now have [`_Thread_local`](https://en.cppreference.com/w/c/language/thread_storage_duration) (since C11). That way the compiler does the heavy lifting work for you. There is also a `thread_local` macro (to use [the same name as in C++11](https://en.cppreference.com/w/cpp/language/storage_duration)) – Alexis Wilke Aug 06 '21 at 05:16