Захват мьютекса
Захват мьютекса
Захват мьютекса может производиться тремя разными функциями, в основе которых лежит функция из native QNX API SyncMutexLock().
Простой захват
int pthread_mutex_lock(pthread_mutex_t* mutex);
Функция захватывает мьютекс, на который ссылается mutex. Если мьютекс уже захвачен другим потоком, то вызвавший поток блокируется до освобождения мьютекса и после этого захватывает его. Только после этого функция pthread_mutex_lock() возвращает управление. Если захватить мьютекс пытается поток, который им уже владеет, то поведение функции pthread_mutex_lock() будет зависеть от значений атрибутов мьютекса, указанных при его создании. QNX предоставляет возможность рекурсивного захвата мьютекса при соответствующих настройках атрибутов (см. выше раздел «Параметры мьютекса»). При создании мьютекса с параметрами по умолчанию попытка повторного захвата мьютекса ни к чему не приводит. Если включен режим контроля ошибок и отключен рекурсивный захват мьютекса, функция pthread_mutex_lock() возвращает EDEADLK при попытке повторного захвата мьютекса тем же потоком.
Функция pthread_mutex_lock() может возвращать следующие значения: EOK — успешное завершение;
EAGAIN — недостаточно системных ресурсов для захвата мьютекса;
EDEADLK — вызывающий поток уже владеет мьютексом и мьютекс не поддерживает рекурсивный захват (режим контроля ошибок);
EINVAL — некорректное значение параметра mutex.
Попытка захвата
int pthread_mutex_trylock(pthread_mutex_t* mutex);
Функция проверяет, свободен ли мьютекс mutex, и если да, то она захватывает его. В противном случае функция возвращает значение EBUSY.
Возвращаемые значения:
EOK — успешное завершение;
EAGAIN — недостаточно системных ресурсов для захвата мьютекса;
EBUSY — мьютекс mutex уже захвачен;
EINVAL — некорректное значение параметра mutex.
Захват с установкой времени ожидания
#include <pthread.h>
#include <time.h>
int pthread_mutex_timedlock(pthread_mutex_t* mutex,
const struct timespec* abs_timeout);
Функция проверяет, свободен ли мьютекс (mutex), и если да, то поток, в котором вызвана функция, захватывает этот мьютекс. Если мьютекс уже захвачен, вызвавший поток блокируется до освобождения мьютекса либо до наступления времени, указанного в аргументе abs_timeout. Если это время уже наступило, поток не блокируется вообще, но захват все-таки произойдет, если мьютекс свободен.
Наступление времени определяется по часам REALTIME_CLOCK, когда значение часов оказывается равным или большим значения, указанного в abs_timeout. Тип данных timespec определен в файле <time.h>.
Если мьютекс создан с атрибутом протокола PRIO_INHERIT, то после выхода потока из блокировки на мьютексе по тайм-ауту приоритет владельца мьютекса подвергается пересмотру в соответствии с приоритетами потоков, оставшихся в очереди на захват мьютекса.
Возвращаемые значения:
EOK — успешное завершение;
EAGAIN — недостаточно системных ресурсов для захвата мьютекса;
EDEADLK — вызывающий поток уже владеет мьютексом, который не поддерживает рекурсивный захват (режим контроля ошибок);
EINVAL — мьютекс использует протокол граничного приоритета для предотвращения инверсии (атрибут protocol установлен в значение PTHREAD_PRIO_PROTECT), но приоритет вызвавшего потока выше граничного приоритета, присвоенного мьютексу; поток должен быть блокирован (мьютекс не свободен), а значение поля abs_timeout, показывающее количество наносекунд, меньше нуля или больше 1000 миллионов; переменная, на которую указывает mutex, не является инициированным объектом — мьютексом.
ETIMEDOUT — мьютекс не может быть захвачен, поскольку указанный тайм-аут истек.
Данный текст является ознакомительным фрагментом.