pthread_setname_np(3)

πŸ’– pthread_setname_np(3) β€” the manual page, but make it cute πŸ’–

okay bestie, gather round, because today we're talking about pthread_setname_np and pthread_getname_np from the pthread_setname_np(3) manual page β€” yes the whole page, no skips, we're doing this properly. it's giving "naming your threads so your debugger doesn't look like a hostage situation" energy and honestly? iconic. 🧡✨


🌸 NAME 🌸

pthread_setname_np, pthread_getname_np β€” set/get the name of a thread 🏷️

πŸ“š LIBRARY πŸ“š

POSIX threads library (libpthread, -lpthread) 🫢

✨ SYNOPSIS ✨

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <pthread.h>

int pthread_setname_np(pthread_t thread, const char *name);
int pthread_getname_np(size_t size;
                       pthread_t thread, char name[size], size_t size);

yes bestie the second declaration looks like that in the source, we do not fix it, we reproduce it, that's the rule πŸ’…

πŸ’… DESCRIPTION πŸ’…

so. by default, every single thread you make with pthread_create() just inherits the program name. every one. all of them. same name. chaos. πŸ’€

enter pthread_setname_np() β€” it lets you give a thread its own unique name, which is lowkey invaluable when you're debugging multithreaded apps and you need to know which thread did the crime. πŸ”

the thread name is a meaningful C language string, and its length is restricted to 16 characters, including the terminating null byte ('\0'). so 15 visible chars, bestie, that's the budget, spend it wisely. πŸŽ€

  • the thread argument says which thread's name you're changing
  • name is the new name, periodt

and pthread_getname_np()? that's the reverse girlypop β€” it retrieves a thread's name. πŸͺž

  • thread specifies the thread whose name you want
  • the buffer name is what the thread name gets returned in
  • size is how many bytes are available in name
  • the buffer given by name should be at least 16 characters in length
  • the returned thread name in the output buffer will be null terminated

no cap, 16 chars. that's the vibe check. ⭐

πŸ”₯ RETURN VALUE πŸ”₯

  • on success, these functions return 0 βœ…
  • on error, they return a nonzero error number ❌

😭 ERRORS 😭

pthread_setname_np() can fail with this one:

  • ERANGE β€” the length of the string pointed to by name exceeds the allowed limit. too long bestie, it said 16, it meant 16. 🚫

pthread_getname_np() can fail with this one:

  • ERANGE β€” the buffer specified by name and size is too small to hold the thread name. tiny buffer, big name energy, and not in a good way. πŸ™ˆ
also, if either of these functions fails to open /proc/self/task/tid/comm, then the call may fail with one of the errors described in open(2). so like, it's not always about the name, sometimes the filesystem is just having a day. πŸŒ€

🫢 ATTRIBUTES 🫢

for an explanation of the terms used in this section, see attributes(7).

  • Interface: pthread_setname_np(), pthread_getname_np()
  • Attribute: Thread safety
  • Value: MT-Safe

slay, they're thread safe, we love a function that doesn't betray you. πŸ‘‘

πŸ‘‘ STANDARDS πŸ‘‘

GNU β€” hence the suffix "_np" (nonportable) in the names. so like, it works here, but don't go assuming every libc is gonna hold your hand. iykyk. 🌈

πŸ¦‹ HISTORY πŸ¦‹

glibc 2.12. blast from the past, but a good one. πŸ’œ

πŸ“ NOTES πŸ“

  • pthread_setname_np() internally writes to the thread-specific comm file under the /proc filesystem: /proc/self/task/tid/comm
  • pthread_getname_np() retrieves it from the same location

secretly it's all just files, bestie, it's always files. πŸ“

πŸŽ€ EXAMPLES πŸŽ€

the program below demonstrates the use of pthread_setname_np() and pthread_getname_np().

and here's a sample run of the program from a shell session:

$ ./a.out;
Created a thread.  Default name is: a.out
The thread name after setting it is THREADFOO.
^Z                           # Suspend the program
[1]+  Stopped           ./a.out
$ ps H -C a.out -o 'pid tid cmd comm'
  PID   TID CMD                         COMMAND
 5990  5990 ./a.out                     a.out
 5990  5991 ./a.out                     THREADFOO
$ cat /proc/5990/task/5990/comm
a.out
$ cat /proc/5990/task/5991/comm
THREADFOO

look at those two cat calls proving the whole thing. the comm file said what it said. 😌

🌸 Program source 🌸

#define _GNU_SOURCE
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define NAMELEN 16

static void *
threadfunc(void *parm)
{
    sleep(5);          // allow main program to set the thread name
    return NULL;
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    int rc;
    char thread_name[NAMELEN];

    rc = pthread_create(&thread, NULL, threadfunc, NULL);
    if (rc != 0)
        errc(EXIT_FAILURE, rc, "pthread_create");

    rc = pthread_getname_np(thread, thread_name, NAMELEN);
    if (rc != 0)
        errc(EXIT_FAILURE, rc, "pthread_getname_np");

    printf("Created a thread.  Default name is: %s\n", thread_name);
    rc = pthread_setname_np(thread, (argc > 1) ? argv[1] : "THREADFOO");
    if (rc != 0)
        errc(EXIT_FAILURE, rc, "pthread_setname_np");

    sleep(2);

    rc = pthread_getname_np(thread, thread_name, NAMELEN);
    if (rc != 0)
        errc(EXIT_FAILURE, rc, "pthread_getname_np");
    printf("The thread name after setting it is %s.\n", thread_name);

    rc = pthread_join(thread, NULL);
    if (rc != 0)
        errc(EXIT_FAILURE, rc, "pthread_join");

    printf("Done\n");
    exit(EXIT_SUCCESS);
}

copy it, run it, NAMELEN 16 is right there doing the lord's work. πŸ”₯

πŸ’œ SEE ALSO πŸ’œ


that's the whole page bestie, every flag, every error, every byte of that hex-free 16-char limit. go forth and name your threads something cute. πŸ¦‹πŸ’–

sign-off time: this lil treasure came from Linux man-pages 6.20 and it's dated 2026-02-08. πŸŽ€ thanks for reading, ily, now go pthread_join something before it leaks. πŸ’…βœ¨
πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: Linux-man-pages-copyleft
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms