Naming threads

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;
}