EDEADLK — вызывающий поток уже владеет мьютексом, который не поддерживает рекурсивный захват (режим контроля ошибок);

EINVAL — мьютекс использует протокол граничного приоритета для предотвращения инверсии (атрибут protocol установлен в значение PTHREAD_PRIO_PROTECT), но приоритет вызвавшего потока выше граничного приоритета, присвоенного мьютексу; поток должен быть блокирован (мьютекс не свободен), а значение поля abs_timeout, показывающее количество наносекунд, меньше нуля или больше 1000 миллионов; переменная, на которую указывает mutex, не является инициированным объектом — мьютексом.

ETIMEDOUT — мьютекс не может быть захвачен, поскольку указанный тайм-аут истек.

<p>Освобождение мьютекса</p>

int pthread_mutex_unlock(pthread_mutex_t* mutex);

Функция pthread_mutex_unlock() освобождает мьютекс, на который ссылается переменная mutex. Вызвавший поток должен быть владельцем мьютекса. Если есть потоки, блокированные в ожидании освобождения мьютекса, то поток с наивысшим приоритетом (или при равных приоритетах дольше всех ждавший) выходит из блокированного состояния и становится владельцем мьютекса.

Для мьютексов, разрешающих рекурсивный захват, функция освобождения должна вызываться столько же раз, сколько и функция захвата.

Возвращаемые значения:

EOK — успешное завершение;

EINVAL — переменная, на которую указывает mutex, не является инициализированным объектом — мьютексом;

EPERM — вызвавший поток не является владельцем мьютекса.

<p>Разрушение объекта мьютекс</p>

int pthread_mutex_destroy(pthread_mutex_t* mutex);

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

Возвращаемые значения:

EOK — успешное завершение;

EBUSY- мьютекс захвачен и не может быть разрушен до освобождения;

EINVAL — переменная, на которую указывает mutex, не является инициированным объектом - мьютексом.

<p>Операции, не поддерживаемые POSIX</p>

В native QNX API есть ряд функций работы с мьютексом, которые не определены POSIX-стандартом, однако они могут оказаться весьма полезными. Поскольку тип POSIX-мьютекса порождается от sync_t, то вполне возможно использование комбинации функций, определенных POSIX, и «родных» native-функций QNX. Однако необходимо помнить, что в таком случае ни о какой межсистемной совместимости говорить уже не приходится.

Восстановление «мертвого» мьютекса

#include

int SyncMutexRevive(sync_t* sync);

int SyncMutexRevive_r(sync_t* sync);

Эти функции[36] предназначены для восстановления мьютекса, который находится в состоянии блокирования DEAD. Мьютекс попадает в состояние DEAD, когда память, использованная при захвате мьютекса, освобождается. Такое может произойти, например, когда умирает поток, захвативший мьютекс, расположенный в разделяемой памяти. В результате вызова вызвавший поток становится владельцем мьютекса, и его счетчик захватов устанавливается в 1 для рекурсивного мьютекса.

Ошибки выполнения функции:

ЕFAULT — ошибка при обращении к указанным в аргументах переменным;

EINVAL — указанный объект синхронизации не существует или не находится в состоянии DEAD;

ETIMEDOUT — отмена вызова по тайм-ауту ядра (устанавливается вызовом TimerTimeout()).

Установка уведомления о «смерти» мьютекса

Определить состояние мьютекса как DEAD можно с помощью функции SyncMutexEvent(), которая определяет событие, связанное со «смертью» мьютекса.

#include

int SyncMutexEvent(sync_t* sync, struct sigevent* event);

int SyncMutexEvent_r(sync_t* sync, struct sigevent* event);

Данная функция предназначена для установки обработчика ситуации, когда мьютекс попадает в состояние DEAD (то есть перераспределяется память, из которой произошел захват мьютекса). Захватить мьютекс, оказавшийся в состоянии DEAD, можно далее с помощью вызова функции SyncMutexRevive().

Ошибки выполнения функции:

EAGAIN — в данный момент ядро не имеет ресурсов для обработки запроса;

EFAULT — ошибка произошла при попытке обращения к sync;

EINVAL — объект синхронизации, на который указывает sync, не существует.

<p>Пример применения мьютекса</p>
Перейти на страницу:

Все книги серии High tech

Нет соединения с сервером, попробуйте зайти чуть позже