PTHREAD_MUTEXATTR_SETROBUST_NP(3)

πŸ’– pthread_mutexattr_getrobust(3) β€” Library Functions Manual πŸ’–

okay bestie, sit down, hydrate, and let's talk about robust mutexes because this one is genuinely so cool and also carries a lot of responsibility ✨


🌸 NAME 🌸

pthread_mutexattr_getrobust, pthread_mutexattr_setrobust β€” get and set the robustness attribute of a mutex attributes object


πŸŽ€ LIBRARY πŸŽ€

POSIX threads library (libpthread, -lpthread)


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <pthread.h>

int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr,
                                int *robustness);
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr,
                                int robustness);

✨ Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

pthread_mutexattr_getrobust(), pthread_mutexattr_setrobust():
    _POSIX_C_SOURCE >= 200809L

πŸ’… DESCRIPTION πŸ’…

So pthread_mutexattr_getrobust() takes the value of the robustness attribute of the mutex attributes object that attr points at, and parks it in *robustness. Simple. Iconic.

And pthread_mutexattr_setrobust() sets that same robustness attribute on the object attr points at, to whatever you passed in *robustness. (yes, the manpage really writes *robustness there, we're not fighting it πŸ’€)

The robustness attribute is literally the vibe check on what a mutex does when its owning thread dies without unlocking it. Unhinged behavior, honestly. Here are the valid values for robustness:

  • PTHREAD_MUTEX_STALLED β€” this is the default for a mutex attributes object. If a mutex gets initialized with the PTHREAD_MUTEX_STALLED attribute and its owner dies without unlocking it, the mutex stays locked forever afterwards, and every future attempt to call pthread_mutex_lock(3) on that mutex will block indefinitely. Yeah. Forever. Not dramatic, just facts. 😭
  • PTHREAD_MUTEX_ROBUST β€” if a mutex is initialized with the PTHREAD_MUTEX_ROBUST attribute and its owner dies without unlocking it, then any future attempt to call pthread_mutex_lock(3) on this mutex will succeed and return EOWNERDEAD, which is the "hey the original owner doesn't exist anymore and this mutex is in an inconsistent state" notification. Usually, after you get EOWNERDEAD back, the next owner should call pthread_mutex_consistent(3) on the acquired mutex to make it consistent again before using it any further. Slay responsibly.

Now, if the next owner unlocks the mutex using pthread_mutex_unlock(3) before making it consistent, the mutex becomes permanently unusable, and any subsequent attempts to lock it using pthread_mutex_lock(3) will fail with the error ENOTRECOVERABLE. For real. The only permitted operation on a mutex in that state is pthread_mutex_destroy(3). That's it. That's the whole guest list.

And if the next owner terminates before calling pthread_mutex_consistent(3), further pthread_mutex_lock(3) operations on this mutex will still return EOWNERDEAD.

🫢 Also important: the attr argument of pthread_mutexattr_getrobust() and pthread_mutexattr_setrobust() should refer to a mutex attributes object that was initialized by pthread_mutexattr_init(3). Otherwise the behavior is undefined. Do not freestyle this one, bestie.

⭐ RETURN VALUE ⭐

On success, these functions return 0. On error, they return a positive error number.

In the glibc implementation, pthread_mutexattr_getrobust() always returns zero. Every time. Always. πŸ’€


πŸ’€ ERRORS πŸ’€

  • EINVAL β€” a value other than PTHREAD_MUTEX_STALLED or PTHREAD_MUTEX_ROBUST was passed to pthread_mutexattr_setrobust().

🌈 VERSIONS 🌈

In the Linux implementation, when you're using process-shared robust mutexes, a waiting thread also receives the EOWNERDEAD notification if the owner of a robust mutex performs an execve(2) without first unlocking the mutex. POSIX.1 does not specify this little detail, but the same behavior also occurs in at least some other implementations. So it's giving "unofficial but widely agreed upon" energy ✨


πŸ‘‘ STANDARDS πŸ‘‘

POSIX.1-2008. We stay standards-compliant. Periodt.


🌸 HISTORY 🌸

glibc 2.12. POSIX.1-2008.

Okay so here's the lore πŸ«– β€” before pthread_mutexattr_getrobust() and pthread_mutexattr_setrobust() got added to POSIX, glibc defined the following equivalent nonstandard functions if _GNU_SOURCE was defined:

[[deprecated]]
int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *attr,
                                   int *robustness);
[[deprecated]]
int pthread_mutexattr_setrobust_np(const pthread_mutexattr_t *attr,
                                   int robustness);

And correspondingly, the constants PTHREAD_MUTEX_STALLED_NP and PTHREAD_MUTEX_ROBUST_NP were also defined.

These GNU-specific APIs first appeared in glibc 2.4, and nowadays they're obsolete and should not be used in new programs. Since glibc 2.34 these APIs are marked as deprecated. So like… respectfully, retire them. πŸ™ˆ


πŸŽ€ EXAMPLES πŸŽ€

The program below demonstrates the use of the robustness attribute of a mutex attributes object. In this program, a thread holding the mutex dies prematurely without unlocking the mutex. The main thread subsequently acquires the mutex successfully and gets the error EOWNERDEAD, after which it makes the mutex consistent.

The following shell session shows what we see when running this program:

$ ./a.out;
[original owner] Setting lock...
[original owner] Locked.  Now exiting without unlocking.
[main] Attempting to lock the robust mutex.
[main] pthread_mutex_lock() returned EOWNERDEAD
[main] Now make the mutex consistent
[main] Mutex is now consistent; unlocking

πŸ¦‹ Program source πŸ¦‹

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

static pthread_mutex_t mtx;

static void *
original_owner_thread(void *ptr)
{
    printf("[original owner] Setting lock...\n");
    pthread_mutex_lock(&mtx);
    printf("[original owner] Locked.  Now exiting without unlocking.\n");
    pthread_exit(NULL);
}

int
main(void)
{
    pthread_t thr;
    pthread_mutexattr_t attr;
    int s;

    pthread_mutexattr_init(&attr);

    pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);

    pthread_mutex_init(&mtx, &attr);

    pthread_create(&thr, NULL, original_owner_thread, NULL);

    sleep(2);

    /* "original_owner_thread" should have exited by now.  */

    printf("[main] Attempting to lock the robust mutex.\n");
    s = pthread_mutex_lock(&mtx);
    if (s == EOWNERDEAD) {
        printf("[main] pthread_mutex_lock() returned EOWNERDEAD\n");
        printf("[main] Now make the mutex consistent\n");
        s = pthread_mutex_consistent(&mtx);
        if (s != 0)
            errc(EXIT_FAILURE, s, "pthread_mutex_consistent");
        printf("[main] Mutex is now consistent; unlocking\n");
        s = pthread_mutex_unlock(&mtx);
        if (s != 0)
            errc(EXIT_FAILURE, s, "pthread_mutex_unlock");

        exit(EXIT_SUCCESS);
    } else if (s == 0) {
        printf("[main] pthread_mutex_lock() unexpectedly succeeded\n");
        exit(EXIT_FAILURE);
    } else {
        printf("[main] pthread_mutex_lock() unexpectedly failed\n");
        errc(EXIT_FAILURE, s, "pthread_mutex_lock");
    }
}

🌟 SEE ALSO 🌟


and that's the whole page, bestie!! πŸ’–βœ¨ this one came from Linux man-pages 6.20, dated 2026-02-08, and you can find it filed under pthread_mu...r_setrobust(3) in the Library Functions Manual. go make your mutexes robust, and please, for the love of everything, call pthread_mutex_consistent(3) before you unlock. mwah πŸ«ΆπŸŽ€πŸŒΈ

πŸ“¦ 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