Ожидать на условной переменной (condition variable)
#include <pthread.h>int pthread_cond_wait_interruptible( pthread_cond_t *cond,pthread_mutex_t *mutex );
libc
Функция pthread_cond_wait_interruptible() блокирует текущий поток на условной переменной cond и разблокирует мьютекс, определяемый параметром mutex. Поток, стремящийся выполнить ожидание на условной переменной, должен предварительно завладеть мьютексом mutex. При возвращении управления из функции будет выполнен повторный захват мьютекса mutex текущим потоком.
Вызывающий поток будет оставаться в блокированном состоянии до тех пор, пока другой поток не выполнит одиночную или широковещательную операцию разблокирования условной переменной. Другим условием разблокирования условной переменной является доставка сигнала текущему потоку или его завершение (cancel). Ожидание на условной переменной является точкой отметы (cancellation point). Во всех рассмотренных случаях в процессе завершения потоком ожидания условной переменной будет производиться захват мьютекса mutex.
Не используйте рекурсивные мьютексы для разграничения доступа к условным переменным. |
В случае завершения (cancel) потока, заблокированного в ожидании условной переменной, будет произведен повторный захват ассоциированного мьютекса. Таким образом, обработчики освобождения ресурсов потока будут исполняться в том же окружении, что и кринтический код до и после рассматриваемой функции. Если в обсуждаемом сценарии мьютексом владеет другой поток, то текущий получит управление лишь после освобождения его блокировки.
Убедитесь в том, что обработчики освобождения ресурсов потока разблокируют мьютекс разграничения доступа к условной переменной. |
Использование условной переменной для синхронизации доступа потоков "производитель" и "потребитель":
#include <stdio.h>#include <pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;int condition = 0;int count = 0;int consume( void ){while ( 1 ){pthread_mutex_lock( &mutex );while ( condition == 0 )pthread_cond_wait_interruptible( &cond, &mutex );printf( "Consumed %d\n", count );condition = 0;pthread_cond_signal( &cond );pthread_mutex_unlock( &mutex );}return (0);}void * produce( void *arg ){while ( 1 ){pthread_mutex_lock( &mutex );while ( condition == 1 )pthread_cond_wait_interruptible( &cond, &mutex );printf( "Produced %d\n", count++ );condition = 1;pthread_cond_signal( &cond );pthread_mutex_unlock( &mutex );}return (0);}int main( void ){pthread_create( NULL, NULL, &produce, NULL );return (consume());}
ЗОСРВ «Нейтрино»
ЗОСРВ
«Нейтрино»
редакции 2018
pthread_cond_broadcast(), pthread_cond_init(), pthread_cond_signal(), pthread_cond_timedwait(), SyncCondvarWait()
Предыдущий раздел: Описание API системной библиотеки