условной переменной cond
, после чего поток предпринимает попытку захвата своего мьютекса. Если есть несколько потоков с равным (и высшим) приоритетом, блокированных на условной переменной, то разблокируется тот поток, который ожидал дольше остальных.
Возвращаемые значения:
EOK
— успешное завершение;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex
;
EINVAL
— не инициализирована переменная, на которую указывает cond
.
int pthread_cond_broadcast(pthread_cond_t* cond);
Вызов функции разблокирует все потоки, блокированные на условной переменной cond
. Потоки разблокируются в порядке приоритетов. Для потоков равного приоритета разблокирование проводится в порядке FIFO.
Возвращаемые значения:
EOK
— успешное завершение;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex
;
EINVAL
— не инициализирована переменная, на которую указывает cond
.
Разрушение условной переменной
int pthread_cond_destroy(pthread_cond_t* cond);
Вызов функции деинициализирует условную переменную cond
. Для дальнейшего использования условной переменной, на которую ссылается cond
, ее необходимо инициализировать вызовом pthread_cond_init()
. Функция может использоваться для изменения параметров условной переменной.
Возвращаемые значения:
EOK
— успешное завершение;
EBUSY
— в данный момент другой поток блокирован на условной переменной cond
;
EINVAL
— не инициализирована переменная cond
.
Ждущая блокировка
QNX предоставляет упрощенный вариант использования условной переменной для блокирования (остановки) потока при помощи интерфейса так называемой
За этим интерфейсом на самом деле скрывается один мьютекс и несколько дополнительных условных переменных. Использование функций ожидания должно проходить внутри участка кода, отмеченного вызовами блокирования и разблокирования мьютекса, ассоциированного со ждущей блокировкой. Одним из основных недостатков ждущей блокировки является то, что для всех потоков и всех ключей ожидания используется один общий мьютекс. ОС не может никоим образом отслеживать взаимные блокировки потоков при использовании ждущих блокировок. В целом поведение этого средства синхронизации идентично бинарным семафорам, но оно требует дополнительных операций блокирования мьютекса.
Все функции для работы со ждущими блокировками объявлены в файле <pthread.h>
.
Операции со ждущей блокировкой
Захват и освобождение ждущей блокировки
Вызов функций ожидания может производиться только внутри блока захвата и освобождения ждущей блокировки:
int pthread_sleepon_lock(void);
int pthread_sleepon_unlock(void);
Функция захвата pthread_sleepon_lock()
возвращает следующие значения:
EOK
— успешное выполнение;
EDEADLK
— попытка повторного захвата мьютекса;
EAGAIN
— может возникнуть при первом вызове в процессе, если системе не хватает ресурсов для создания внутреннего мьютекса.
Функция освобождения pthread_sleepon_unlock()
возвращает значения:
EOK
— успешное выполнение;
EPERM
— вызвавший поток не является владельцем внутреннего мьютекса.
Функции ожидания
Ожидание выполнения условия для ждущей блокировки может выполняться в двух вариантах: простое ожидание и ожидание с установкой тайм-аута.
int pthread_sleepon_wait(const volatile void* addr);
int pthread_sleepon_timedwait(const volatile void* addr, uint64_t nsec);
При вызове функций ожидания необходимо указать ключ addr
(произвольный адрес в памяти). Если этот адрес указывается впервые, для данного вызова создается новая условная переменная. Поток освобождает захваченный внутренний мьютекс и переходит в состояние блокировки на условной переменной.
Ожидание завершения потока