Under Linux ( and BSD, MacOS, …) it is possible to name threads of a process via pthread_setname_np or prctl(PR_SET_NAME). This can be handy for example when debugging multi-threaded code in gdb or looking at top and figuring out which thread consumes 100% CPU.
In the following this feature is used to name OpenMP threads and make them distinguishable inside gdb. For OpenMP it has to be performed inside a parallel region:
[c]
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, v2, as
// published by the Free Software Foundation
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// File: ThreadName.c
// Setting thread name via pthread_setname_np.
// Compile with:
// gcc -g -fopenmp ThreadName.c -o thread-name
// icc -g -openmp ThreadName.c -o thread-name
//
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#ifdef _OPENMP
#include <openmp.h>
#endif
int main(int argc, char * argv[])
{
#pragma omp parallel
{
int threadId = 0;
char name[16] = { 0 };
#ifdef _OPENMP
threadId = omp_get_thread_num();
#endif
snprintf(name, sizeof(name), „omp-%02d“, threadId);
pthread_setname_np(pthread_self(), name);
sleep(10);
}
return 0;
}
[/c]
[c]
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, v2, as
// published by the Free Software Foundation
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// File: ThreadNamePrctl.c
// Setting thread name via prctl(PR_SET_NAME).
// Compile with:
// gcc -g -fopenmp ThreadName.c -o thread-name-prctl
// icc -g -openmp ThreadName.c -o thread-name-prctl
//
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#include <sys/prctl.h>
int main(int argc, char * argv[])
{
#pragma omp parallel
{
int threadId = 0;
char name[16] = { 0 };
#ifdef _OPENMP
threadId = omp_get_thread_num();
#endif
snprintf(name, sizeof(name) – 1, „omp-%02d“, threadId);
prctl(PR_SET_NAME, name, 0, 0, 0);
sleep(10);
}
return 0;
}
[/c]
Compile ThreadNamePrctl.c with gcc via:
gcc -g -fopenmp ThreadName.c -o thread-name-prctl
Note: -g is only needed for convience when using gdb.
$ env OMP_NUM_THREADS=4 gdb ./thread-name-prctl > break sleep > r > info threads Id Target Id Frame 4 Thread 0x7ffff642d700 (LWP 26499) "omp-03" 0x00007ffff76e1590 in sleep () from /lib64/libc.so.6 3 Thread 0x7ffff6c2e700 (LWP 26498) "omp-02" 0x00007ffff76e1590 in sleep () from /lib64/libc.so.6 2 Thread 0x7ffff742f700 (LWP 26497) "omp-01" 0x00007ffff76e1590 in sleep () from /lib64/libc.so.6 * 1 Thread 0x7ffff7fb9760 (LWP 26493) "omp-00" 0x00007ffff76e1590 in sleep () from /lib64/libc.so.6
Thne named threads will also show up with the same name in top
(when pressing „H“):
... 26504 user-name 20 0 34940 636 500 S 0 0.0 0:00.00 omp-00 26508 user-name 20 0 34940 636 500 S 0 0.0 0:00.00 omp-01 26509 user-name 20 0 34940 636 500 S 0 0.0 0:00.00 omp-02 26510 user-name 20 0 34940 636 500 S 0 0.0 0:00.00 omp-03 ...
Notes:
- The length of a thread name is limited to 16 characters.
- Not all versions of gdb support this feature.
- pthread_setname_np
- It is only supported in glibc since version 2.12.
- Compile with
-pthread
if no OpenMP is used.
- prctl(PR_SET_NAME) could be used as a fallback, which is supported since Linux kernel version 2.6.9.