Выбрать главу

Функция pthread_cond_timedwait() эквивалентна функции pthread_cond_wait (), за исключением того, что она возвращает код ошибки, если абсолютное время, заданное пара м етро м abstime, наступит (т.е. системное время станет равным или превысит значение abstime) до того, как будет передано (с помощью сигнала) условие cond, или если абсолютное время, заданное параметром abstime, уже наступило в момент вызова.

C S Если поддерживается опция Clock Selection, условная переменная будет иметь атрибут часов, определяющий механизм, который предназначен для измерения времени, заданного параметром abstime . По истечении заданного времени функция pthread_cond_timedwait() освободит и снова захватит мьютекс, адресуемый параметром mutex . Функция pthread_cond_timedwait () также представляет собой точку отмены.

Если потоку, ожидающему значения условной переменной, передается сигнал, то при возврате из обработчика сигнала поток возобновит ожидание этой условной переменной (как будто не было никакого прерывания на обработку сигнала) или возвратит нуль вследствие фиктивного запуска.

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

За исключением кода ошибки [ETIMEDOUT], все проверки на наличие ошибок реализованы так, как если бы они были выполнены в самом начале работы каждой функции, и код ошибки в случае ее обнаружения возвращается до модификации состояния мьютекса, заданного пара м етро м mutex, или условной переменной, заданной параметром cond.

При успешном завершении возвращается нулевое значение; в противном случае — код ошибки, обозначающий ее характер.

Ошибки

Функция pthread_cond_timedwait () завершится неудачно, если:

[ETIMEDOUT]  вре м я, заданное пара м етро м abstime, наступило.

Функции pthread_cond_timedwait() и pthread_cond_wait() м огут завершиться неудачно, если:

[EINVAL] значение, заданное хотя бы одни м из пара м етров cond, mutex или abstime, недействительно;

[EINVAL] для выполнения параллельных операций pthread_cond_timedwait() или pthread_cond_wait () по одной и той же условной пере м енной были задействованы различные мьютексы;

[EPERM]  во вре м я вызова любой из функций мьютексом не владел текущий поток.

Эти функции не возвращают код ошибки [EINTR].

Примеры

Отсутствуют.

Замечания по использованию

Отсутствуют.

Логическое обоснование

Семантика ожидания по условию

Важно от м етить, что, когда функции pthread_cond_wait() и pthread_cond_timedwait() завершаются без ошибки, соответствую щ ий предикат может все еще иметь ложное значение. Аналогично, когда функция pthread_cond_timedwait() возвращается с ошибкой истечения времени ожидания, соответствующий предикат может иметь истинное значение из-за неизбежной «гонки» между истечением периода ожидания и изменением состояния предиката.

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

В общем случае при каждом завершении ожидания по условию поток должен оценивать значение предиката, связанного с ожиданием по условию, чтобы узнать, может ли он безопасно продолжать выполнение, ожидать или объявить тайм-аут. Возврат из состояния ожидания не означает, что соответствующий предикат имеет конкретное значение (ЛОЖЬ или ИСТИНА).

Поэтому рекомендуется ожидание по условию выражать в коде, эквивалентно м циклу «while», который выполняет проверку предиката.

Семантика ожидания по времени

Абсолютное время было выбрано для задания параметра лимита времени по двум причинам. Во-первых, несмотря на то, что измерение относительного времени нетрудно реализовать в начале функции, для которой задается абсолютное время, с заданием абсолютного времени в начале функции, которая определяет относительное время, связано условие «гонок». Предположим, например, что функция clock_gettime() возвращает текущее время, а функция cond_relative_timed_wait () использует относительное время.

clock_gettime(CLOCK_REALTIME, &now)

reltime = sleep_til_this_absolute_time -now;

cond_relative_timed_wait (с, m, &reltime);

Если поток выгружается между первой и последней инструкциями, поток блокируется слишком надолго. Однако блокирование несущественно, если используется абсолютное время. Кроме того, абсолютное время не нужно пересчитывать, если оно используется в цикле несколько раз.