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

НАИМЕНОВАНИЕ
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)