pthread_mutexattr_setrobust(3)

NUME
pthread_mutexattr_getrobust, pthread_mutexattr_setrobust - obține și definește atributul de robustețe al unui obiect cu atribute mutex

BIBLIOTECA
Biblioteca de fire de execuție POSIX (libpthread, -lpthread)

SINOPSIS
#include <pthread.h>

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

    Cerințe pentru macrocomenzi de testare a caracteristicilor pentru glibc (consultați feature_test_macros(7)):

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

DESCRIERE
Funcția pthread_mutexattr_getrobust() plasează în *robustness valoarea atributului de robustețe al obiectului de atribute mutex la care se referă attr. Funcția pthread_mutexattr_setrobust() stabilește valoarea atributului robustețe al obiectului atribute mutex la care face referire attr la valoarea specificată în *robustness.

Atributul „robustness” specifică comportamentul mutex-ului atunci când firul proprietar moare fără să deblocheze mutex-ul. Următoarele valori sunt valabile pentru robustness:

PTHREAD_MUTEX_STALLED
    Aceasta este valoarea implicită pentru un obiect cu atribute mutex. Dacă un mutex este inițializat cu atributul PTHREAD_MUTEX_STALLED și proprietarul său moare fără să-l deblocheze, mutex-ul rămâne blocat ulterior și orice încercare viitoare de a apela pthread_mutex_lock(3) pe mutex se va bloca pe termen nelimitat.

PTHREAD_MUTEX_ROBUST
    Dacă un mutex este inițializat cu atributul PTHREAD_MUTEX_ROBUST și proprietarul său moare fără a-l debloca, orice încercare viitoare de a apela pthread_mutex_lock(3) pe acest mutex va reuși și va returna EOWNERDEAD pentru a indica faptul că proprietarul inițial nu mai există și că mutex-ul este într-o stare inconsistentă. De obicei, după ce EOWNERDEAD este returnat, următorul proprietar ar trebui să apeleze pthread_mutex_consistent(3) pe mutex-ul achiziționat pentru a-l face din nou consistent înainte de a-l utiliza în continuare.

    Dacă următorul proprietar deblochează mutex-ul folosind pthread_mutex_unlock(3) înainte de a-l face consistent, mutex-ul va fi permanent inutilizabil și orice încercare ulterioară de a-l bloca folosind pthread_mutex_lock(3) va eșua cu eroarea ENOTRECOVERABLE. Singura operație permisă pe un astfel de mutex este pthread_mutex_destroy(3).

    Dacă următorul proprietar încetează activitatea înainte de a apela pthread_mutex_consistent(3), operațiile ulterioare pthread_mutex_lock(3) asupra acestui mutex vor returna în continuare EOWNERDEAD.

Rețineți că argumentul attr din pthread_mutexattr_getrobust() și pthread_mutexattr_setrobust() trebuie să se refere la un obiect de atribute mutex care a fost inițializat de pthread_mutexattr_init(3), în caz contrar comportamentul este indefinit.

VALOAREA RETURNATĂ
În caz de succes, aceste funcții returnează 0. În caz de eroare, acestea returnează un număr pozitiv de eroare.

În implementarea glibc, pthread_mutexattr_getrobust() returnează întotdeauna zero.

ERORI-IEȘIRE

EINVAL
    O altă valoare decât PTHREAD_MUTEX_STALLED sau PTHREAD_MUTEX_ROBUST a fost trecută la pthread_mutexattr_setrobust().

VERSIUNI
În implementarea Linux, atunci când se utilizează mutex-uri robuste partajate de proces, un fir în așteptare primește și notificarea EOWNERDEAD dacă proprietarul unui mutex robust efectuează un execve(2) fără a debloca mai întâi mutex-ul. POSIX.1 nu specifică acest detaliu, dar același comportament apare și în cel puțin alte implementări.

STANDARDE
POSIX.1-2008.

ISTORIC
glibc 2.12. POSIX.1-2008.

Înainte de adăugarea la POSIX a funcțiilor pthread_mutexattr_getrobust() și pthread_mutexattr_setrobust(), glibc a definit următoarele funcții non-standard echivalente dacă _GNU_SOURCE era definită:

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

În consecință, au fost definite și constantele PTHREAD_MUTEX_STALLED_NP și PTHREAD_MUTEX_ROBUST_NP.

Aceste API-uri specifice GNU, care au apărut pentru prima dată în glibc 2.4, sunt în prezent învechite și nu ar trebui utilizate în programe noi; începând cu glibc 2.34 aceste API-uri sunt marcate ca fiind depreciate.

EXEMPLE
Programul de mai jos demonstrează utilizarea atributului „robustness” al unui obiect cu atribute mutex. În acest program, un fir care deține mutex-ul moare prematur fără să deblocheze mutex-ul. Firul principal dobândește ulterior mutex-ul cu succes și primește eroarea EOWNERDEAD, după care face mutex-ul consistent.

Următoarea sesiune shell arată ce vedem la rularea acestui program:

    $ ./a.out;
    [proprietarul original ] Amplasarea blocării...
    [proprietarul original] Blocat. Acum ies fără să deblochez.
    [main] Se încearcă blocarea mutex-ului robust.
    [main] pthread_mutex_lock() a returnat EOWNERDEAD
    [main] Acum se face mutex-ul consistent
    [main] Mutex-ul este acum consistent; se deblochează

  Sursa programului
    #include <errno.h>
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    #define handle_error_en(en, msg) \
            do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

    static pthread_mutex_t mtx;

    static void *
    original_owner_thread(void *ptr)
    {
        printf("[proprietarul original ] Amplasarea blocării...\n");
        pthread_mutex_lock(&mtx);
        printf("[proprietarul original] Blocat. Acum ies fără să deblochez.\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” ar trebui să fi ieșit până acum.  */

        printf("[main] Se încearcă blocarea mutex-ului robust.\n");
        s = pthread_mutex_lock(&mtx);
        if (s == EOWNERDEAD) {
            printf("[main] pthread_mutex_lock() a returnat EOWNERDEAD\n");
            printf("[main] Acum se face mutex-ul consistent\n");
            s = pthread_mutex_consistent(&mtx);
            if (s != 0)
                handle_error_en(s, "pthread_mutex_consistent");
            printf("[main] Mutex-ul este acum consistent; se deblochează\n");
            s = pthread_mutex_unlock(&mtx);
            if (s != 0)
                handle_error_en(s, "pthread_mutex_unlock");

            exit(EXIT_SUCCESS);
        } else if (s == 0) {
            printf("[main] pthread_mutex_lock() a reușit în mod neașteptat\n");
            exit(EXIT_FAILURE);
        } else {
            printf("[main] pthread_mutex_lock() a eșuat în mod neașteptat[main]\n");
            handle_error_en(s, "pthread_mutex_lock");
        }
    }

CONSULTAȚI ȘI
get_robust_list(2), set_robust_list(2), pthread_mutex_consistent(3), pthread_mutex_init(3), pthread_mutex_lock(3), pthreads(7)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.