Ожидать условную переменную в течении ограниченного времени
#include <pthread.h>#include <time.h>int pthread_cond_timedwait( pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime );
libc
Функция pthread_cond_timedwait() блокирует вызывающий поток на условной переменной cond и освобождает ассоциированный с ней мьютекс mutex. Вызывающий поток должен иметь мьютекс mutex в блокированном состояни перед вызовом данной функции. При возвращении управления функцией мьютекс будет снова заблокирован, а текущий поток будет являться владельцем.
Заблокированный поток будет оставаться таким до тех пор, пока иной поток не выполнит одиночное или массовое разблокирование на условной переменной (см. pthread_cond_signal() и pthread_cond_broadcast()). Абсолютный интервал времени, заданный в abstime, определяет предельное время доставки принудительного разблокирующего сигнала уже не от прикладного потока, а от ядра ОС. Стоит учитывать, что в этот момент может произойти прерывание выполнения потока так как ожидание на условной переменной является точкой остановки потока. В любом случае перед разблокированием поток становится владельцем разблокированного мьютекса.
Для определения типа таймера, который контролирует таймауты условной переменной можно использовать функцию pthread_condattr_setclock(). При этом CLOCK_MONOTONIC
не зависит от изменений системного времени и используется по умолчанию, а CLOCK_REALTIME
наоборот.
Не используйте рекурсивные мьютексы с условными переменными. |
Если заблокированный на условной переменной поток прерывает свое выполнение, то происходит захват ассоциированного мьютекса и выполнение всех определенных в потоке деструкторов уже в контексте критической секции кода, которая организована до и после самого вызова pthread_cond_timedwait(). Если кто-то иной владеет мьютексом, прерывание потока откладывается до его разблокирования.
|
Подождать 5 секунд перед попыткой захватить контроль над условной переменной:
#include <errno.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t c;int main( int argc, char* argv[] ){struct timespec to;int retval;pthread_condattr_t attr;fprintf( stderr, "starting...\n" );/* Set up the condvar attributes to use CLOCK_MONOTONIC. */pthread_condattr_init( &attr );pthread_condattr_setclock( &attr, CLOCK_MONOTONIC );pthread_cond_init( &c, &attr );/** Here's the interesting bit; we'll wait for five seconds* FROM NOW when we call pthread_cond_timedwait().*/clock_gettime( CLOCK_MONOTONIC, &to );to.tv_sec += 5;if ( (retval = pthread_mutex_lock( &m )) ){fprintf( stderr, "pthread_mutex_lock %s\n", strerror( retval ) );exit( EXIT_FAILURE );}if ( (retval = pthread_cond_timedwait( &c, &m, &to )) ){fprintf( stderr, "pthread_cond_timedwait %s\n", strerror( retval ) );exit( EXIT_FAILURE );}if ( (retval = pthread_mutex_unlock( &m )) ){fprintf( stderr, "pthread_mutex_unlock %s\n", strerror( retval ) );exit( EXIT_FAILURE );}return (EXIT_SUCCESS);}
POSIX 1003.1 Threads
nsec2timespec(), pthread_cond_broadcast(), pthread_cond_init(), pthread_cond_signal(), pthread_cond_wait(), pthread_cond_wait_interruptible(), pthread_condattr_setclock(), SyncCondvarWait(), TimerTimeout(), struct timespec, timespec2nsec()
Предыдущий раздел: Описание API системной библиотеки