Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       pthread_mutexattr_getrobust,  pthread_mutexattr_setrobust  - возвращает и изменяет атрибут устойчивости в
       объекте мьютексных атрибутов

БИБЛИОТЕКА

       Библиотека потоков POSIX (libpthread, -lpthread)

ОБЗОР

       #include <pthread.h>

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

   Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

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

ОПИСАНИЕ

       Функция pthread_mutexattr_getrobust() помещает значение атрибута  устойчивости  (robustness)  из  объекта
       мьютексных  атрибутов,  на  который  указывает attr, в *robustness. Функция pthread_mutexattr_setrobust()
       изменяет значение атрибута устойчивости в объекте мьютексных атрибутов, на  который  указывает  attr,  на
       значение, заданное в *robustness.

       Атрибут  устойчивости определяет поведение мьютекса после того как владеющая нить завершает работу, но не
       разблокировала мьютекс. Для robustness возможны следующие значения:

       PTHREAD_MUTEX_STALLED
              Значение по умолчанию для объекта мьютексных атрибутов. Если мьютекс инициализирован  с  атрибутом
              PTHREAD_MUTEX_STALLED  и  его  владелец  завершает  работу  без  его разблокировки, то после этого
              мьютекс остаётся заблокированным и все последующие попытки вызова pthread_mutex_lock(3) для  этого
              мьютекса будут заблокированы навсегда.

       PTHREAD_MUTEX_ROBUST
              Если  мьютекса  инициализирован с атрибутом PTHREAD_MUTEX_ROBUST и и его владелец завершает работу
              без его разблокировки,то все последующие попытки вызова pthread_mutex_lock(3) для  этого  мьютекса
              будут  успешно  выполнены  возвращается EOWNERDEAD, чтобы показать, что первоначальный владелец не
              существует и мьютекс находится в неопределенном состоянии. Обычно, после возврата EOWNERDEAD перед
              началом использования следующий владелец должен вызвать pthread_mutex_consistent(3) над полученным
              мьютексом, чтобы снова сделать его согласованным.

              Если следующий владелец разблокирует  мьютекс  с  помощью  pthread_mutex_unlock(3)  до  того,  как
              сделать  его  согласованным,  мьютекс  станет  необратимо  неработоспособен  и последующие попытки
              заблокировать его с помощью pthread_mutex_lock(3) будут завершаться ошибкой  ENOTRECOVERABLE.  Для
              такого мьютекса доступна только одна операция — pthread_mutex_destroy(3).

              Если  следующий  владелец  завершит  работу  до вызова pthread_mutex_consistent(3), то последующие
              операций pthread_mutex_lock(3) с этим мьютексом будут по прежнему возвращать EOWNERDEAD.

       Заметим,  что  аргумент  attr  у  pthread_mutexattr_getrobust()  и  pthread_mutexattr_setrobust()  должен
       указывать  на  объект  мьютексных  атрибутов,  который  был  инициализирован pthread_mutexattr_init(3), в
       противном случае поведение не определено.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При успешном выполнении эти функции возвращают 0. При ошибке возвращается положительный номер ошибки.

       В реализации glibc функция pthread_mutexattr_getrobust() всегда возвращает ноль.

ОШИБКИ

       EINVAL Помимо PTHREAD_MUTEX_STALLED или  PTHREAD_MUTEX_ROBUST  в  pthread_mutexattr_setrobust()  передано
              что-то ещё.

ВЕРСИИ

       В  реализации  Linux  при  использовании  общих  для  процессов устойчивых мьютексов ожидающая нить также
       получает  уведомление  EOWNERDEAD,  если  владелец   устойчивого   мьютекса   выполняет   execve(2)   без
       предварительной  разблокировки  мьютекса.  В POSIX.1 не указана данная подробность, но такое же поведение
       также встречается и в нескольких других реализациях.

СТАНДАРТЫ

       POSIX.1-2008.

ИСТОРИЯ

       glibc 2.12.  POSIX.1-2008.

       До появления pthread_mutexattr_getrobust() и pthread_mutexattr_setrobust() в POSIX,  в  glibc  определись
       следующие эквиваленты нестандартных функций, если определён _GNU_SOURCE:

       [[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);

       Соответственно, также определены константы PTHREAD_MUTEX_STALLED_NP и PTHREAD_MUTEX_ROBUST_NP.

       These  GNU-specific APIs, which first appeared in glibc 2.4, are nowadays obsolete and should not be used
       in new programs; since glibc 2.34 these APIs are marked as deprecated.

ПРИМЕРЫ

       В программе, представленной далее, показывается использование атрибута устойчивости в объекте  мьютексных
       атрибутов.  В  этой  программе  нить,  удерживающая мьютекс, завершает работу без разблокировки мьютекса.
       После этого главная нить захватывает мьютекс и получает ошибку  EOWNERDEAD,  после  чего  делает  мьютекс
       согласованным.

       Пример сеанса работы с программой:

           $ ./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

   Исходный код программы
       #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("[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)
                   handle_error_en(s, "pthread_mutex_consistent");
               printf("[main] Mutex is now consistent; unlocking\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() unexpectedly succeeded\n");
               exit(EXIT_FAILURE);
           } else {
               printf("[main] pthread_mutex_lock() unexpectedly failed\n");
               handle_error_en(s, "pthread_mutex_lock");
           }
       }

СМОТРИТЕ ТАКЖЕ

       get_robust_list(2), set_robust_list(2), pthread_mutex_consistent(3), pthread_mutex_init(3),
       pthread_mutex_lock(3), pthreads(7)

ПЕРЕВОД

       Русский перевод этой страницы руководства разработал(и) Alexey, Azamat Hackimov
       <azamat.hackimov@gmail.com>, kogamatranslator49 <r.podarov@yandex.ru>, Darima Kogan
       <silverdk99@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов
       <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной
       лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
       разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                  pthread_mutexattr_setrobust(3)