Threads show up in process listings with the same name as their parent process which makes them hard to tell apart (this article describes how to list threads). It would be much nicer if the threads were given meaningful names such as “input_task”, “alarm_thread” and so on. In this short note I will show how it is done.
I have a program, called thread_name, with three threads. Normally they show up like this
# ps -Leo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
PID TID CLS RTPRIO NI PRI PSR %CPU STAT WCHAN COMMAND
...
280 280 TS - 0 19 0 1.0 Sl futex_wait thread_name
280 281 TS - 0 19 0 0.0 Sl hrtimer_nanosl thread_name
280 282 TS - 0 19 0 0.0 Sl hrtimer_nanosl thread_name
...
"thread_name" appears three times, but which thread is which? The solution is in the prctl (process control) function which can be used to get or set various attributes of the currently executing process, OR thread. It is defined like this
#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
Option is one of several constants defined in the header file and arg2..arg5 depend on the option. The case of interest here is option PR_SET_NAME which takes a string of up to 16 characters pointed at by arg2, like so
char name [17]; /* Name must be <= 16 characters + a null */
strcpy (name, “input_thread”);
prctl (PR_SET_NAME, (unsigned long)&name);
Now when I run the program I see
# ps -Leo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
PID TID CLS RTPRIO NI PRI PSR %CPU STAT WCHAN COMMAND
...
281 281 TS - 0 19 0 0.4 Sl futex_wait thread_name
281 282 TS - 0 19 0 0.0 Sl hrtimer_nanosl input_thread
281 283 TS - 0 19 0 0.0 Sl hrtimer_nanosl output_thread
...
Here is the full listing of my program
/*
* Set thread names so they show up in process listings.
*/
#include
#include
#include
#include
#include
#include
#include
#define MAX_NAME_LEN 15
static void set_thread_name (char *thread_name)
{
char name [MAX_NAME_LEN + 1]; /* Name must be <= 15 characters + a null */
strncpy (name, thread_name, MAX_NAME_LEN);
name [MAX_NAME_LEN] = 0;
prctl (PR_SET_NAME, (unsigned long)&name);
}
static void *input_thread (void *arg)
{
set_thread_name ("input_thread");
while (1)
sleep (10);
return NULL;
}
static void *output_thread (void *arg)
{
set_thread_name ("output_thread");
while (1)
sleep (10);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t i_t;
pthread_t o_t;
printf ("Threads with names\n");
pthread_create (&i_t, NULL, input_thread, NULL);
pthread_create (&o_t, NULL, output_thread, NULL);
/* Wait for both threads to finish */
pthread_join (i_t, NULL);
pthread_join (o_t, NULL);
return 0;
}