Не следует использовать условную переменную с мьютексом, у которого разрешен рекурсивный захват.
Возвращаемые значения:
EOK
— успешное завершение ожидания либо ожидание прервано сигналом;
EAGAIN
— недостаток системных ресурсов для реализации ожидания на условной переменной;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex;
EINVAL
— возвращается в следующих ситуациях:
• не инициализированы переменные, на которые указывают cond
или mutex;
• попытка использования переменной, на которую указывает cond
, для нескольких мьютексов;
• вызвавший поток не владеет указанным мьютексом.
Ожидание с тайм-аутом
#include
int pthread_cond_timedwait(pthread_cond_t* cond,
pthread_mutex_t* mutex, const struct timespec* abstime);
Поведение функции идентично варианту обычного ожидания, за исключением того, что ожидание может завершиться также при наступлении времени, переданного параметром abstime
.
Следует помнить, что после наступления времени тайм-аута управление совсем не обязательно вернется к вызвавшему потоку. После наступления этого времени функция переведет поток из состояния блокирования на условной переменной в состояние готовности и предпримет попытку захвата мьютекса. Если мьютекс в это время захвачен другим потоком, вызвавший поток перейдет в состояние блокирования на мьютексе.
Возвращаемые значения:
EOK
— успешное завершение ожидания либо ожидание прервано сигналом;
EAGAIN
— недостаток системных ресурсов для реализации ожидания на условной переменной;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex
;
EINVAL
— возвращается в следующих ситуациях:
• не инициализированы переменные, на которые указывают cond
или mutex
;
• попытка использования переменной, на которую указывает cond
, для нескольких мьютексов;
• вызвавший поток не владеет указанным мьютексом.
ETIMEDOUT
— завершение функции по наступлению времени, указанного в abstime.
Штатным способом разблокирования потока, блокированного на условной переменной, является вызов функции, сигнализирующей о выполнении условия. В native API это функция SyncCondvarSignal()
, которая имеет две POSIX-обертки: pthread_cond_signal()
и pthread_cond_broadcast()
. Разница между ними заключается в том, что первая пробуждает только один, самый приоритетный поток из ждущих выполнения условия, а вторая пробуждает все потоки, ожидающие выполнения условия.
Однако необходимо помнить про специфику ожидания внутри критической секции: вызов функции pthread_cond_broadcast()
только переведет ожидающие потоки из состояния блокирования на условной переменной в состояние блокировки на мьютексе, поскольку мьютекс сможет захватить только самый приоритетный поток.
Нештатным способом завершения ожидания на условной переменной может быть приход немаскированного сигнала UNIX. Если для данного сигнала определен обработчик, он выполнится без захвата мьютекса, а попытка захвата будет произведена уже после его завершения.
Выполнение условия для единичного потока
int pthread_cond_signal(pthread_cond_t* cond);
Функция переводит в состояние готовности самый приоритетный поток из блокированных на условной переменной cond
, после чего поток предпринимает попытку захвата своего мьютекса. Если есть несколько потоков с равным (и высшим) приоритетом, блокированных на условной переменной, то разблокируется тот поток, который ожидал дольше остальных.
Возвращаемые значения:
EOK
— успешное завершение;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex
;
EINVAL
— не инициализирована переменная, на которую указывает cond
.
Выполнение условия для всех ожидающих потоков
int pthread_cond_broadcast(pthread_cond_t* cond);
Вызов функции разблокирует все потоки, блокированные на условной переменной cond
. Потоки разблокируются в порядке приоритетов. Для потоков равного приоритета разблокирование проводится в порядке FIFO.
Возвращаемые значения:
EOK
— успешное завершение;
EFAULT
— произошла ошибка при попытке обращения к указателям cond
или mutex
;
EINVAL
— не инициализирована переменная, на которую указывает cond
.
Разрушение условной переменной
Читать дальше
Конец ознакомительного отрывка
Купить книгу