SyncCondvarWait(), SyncCondvarWait_r()

Ожидать условную переменную

Прототип:

#include <sys/neutrino.h>
int SyncCondvarWait( sync_t *sync,
sync_t *mutex );
int SyncCondvarWait_r( sync_t *sync,
sync_t *mutex );

Аргументы:

sync
Указатель на объект синхронизации sync_t. Он должен быть проинициализирован динамически с помощью SyncTypeCreate() или статически с помощью PTHREAD_COND_INITIALIZER.
mutex
Контролирующий условную переменную мьютекс. Он должен быть заблокирован посредством вызова SyncMutexLock() или POSIX-обертки pthread_mutex_lock(). Ядро освобождает мьютекс перед непосредственной блокировкой потока на sync.

Библиотека:

libc

Описание:

Системные вызовы SyncCondvarWait() и SyncCondvarWait_r() блокируют вызывающий поток на объекте синхронизации sync. Если более одного потока оказываются заблокированы, они располагаются в очереди в порядке приоритетов и длительности ожидания. Эти функции эквивалентны, за исключением способа информирования об ошибках.


Note: Вместо явного использования данных системных вызовов следует рассмотреть возможность использования функций pthread_cond_timedwait() и pthread_cond_wait().

Заблокированный поток может быть разблокирован в одном из следующих случаев:

Условная переменная "просигналила"
Был выполнен вызов SyncCondvarSignal(), который определяет, что некоторый поток должен быть разбужен.

Перед выходом из SyncCondvarWait() мьютекс mutex захватывается повторно. Если mutex заблокирован, поток переходит в состояние STATE_MUTEX в ожидании освобождения mutex. Это эквивалентно вызову SyncMutexLock( mutex ).
Таймаут
Ожидание было прервано таймаутом от предшествующего вызова TimerTimeout().

Перед выходом из SyncCondvarWait() мьютекс mutex захватывается повторно. Если mutex заблокирован, поток переходит в состояние STATE_MUTEX в ожидании освобождения mutex. Это эквивалентно вызову SyncMutexLock( mutex ).
POSIX сигнал
Ожидание было прервано незаблокированным сигналом (см. SignalKill()). Если обработчик сигнала был задан, то он выполняется с разблокированным мьютексом mutex. При выходе из обработчика сигнала mutex захватывается повторно. Если mutex заблокирован, поток переходит в состояние STATE_MUTEX в ожидании освобождения mutex. Это эквивалентно вызову SyncMutexLock( mutex ).
Точка остановки потока
Ожидание было прервано вызовом ThreadCancel(). Перед выходом из SyncCondvarWait() мьютекс mutex захватывается повторно. Если mutex заблокирован, поток переходит в состояние STATE_MUTEX в ожидании освобождения mutex. Это эквивалентно вызову SyncMutexLock( mutex ).

Во всех случаях mutex перезахватывается перед возвращением управления в поток. Если поток переходит в состояние STATE_MUTEX, действуют правила вызова SyncMutexLock().

Условные переменные используются для блокирования потоков до достижения определенных условий. Ложные пробуждения могут произойти в следствие таймаутов, сигналов, а также одиночных или массовых освобождений условной переменной. По этой причине следует постоянно контролировать состояние ожидаемого условия, даже при успешном завершении функции. Наиболее простой путь – контроль состояния условной переменной в цикле while. Например:

SyncMutexLock( &mutex );
while ( some_condition )
{
SyncCondvarWait( &condvar, &mutex );
}
SyncMutexUnlock( &mutex );

Состояния блокировки:

STATE_CONDVAR
Вызывающий поток заблокирован в ожидании одиночного или массового освобождения условной переменной.
STATE_MUTEX
Поток был разблокирован из состояния STATE_CONDVAR и в попытке захватить контролирующий мьютекс обнаружено, что он уже занят другим потоком.

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

SyncCondvarWait()
Если возникла ошибка функция возвращает -1, код ошибки записывается в errno. Любое другое возвращенное значение считается успешным завершением.
SyncCondvarWait_r()
EOK возвращается при успешном завершении. Функция НЕ устанавливает errno. При возникновении ошибки функция возвращает один из представленных ниже кодов.

Коды ошибок:

EAGAIN
При первом использовании статически инициализированного объекта sync все объекты синхронизации ядра уже используются.
EFAULT
Возникла ошибка при доступе ядра к объекту sync.
EINTR
Ожидание прервано сигналом.
EINVAL
Объект синхронизации sync не существует.
ETIMEDOUT
Ожидание прервано таймаутом (см. TimerTimeout()).

Классификация:

ЗОСРВ «Нейтрино»

Безопасность использования
Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

sync_t, pthread_cond_broadcast(), pthread_cond_signal(), pthread_cond_timedwait(), pthread_cond_wait(), pthread_cond_wait_interruptible(), pthread_mutex_lock(), SignalKill(), SyncCondvarSignal(), SyncMutexLock(), SyncTypeCreate(), ThreadCancel(), TimerTimeout()




Предыдущий раздел: Описание API системной библиотеки