Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 413

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

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

Поэтому рекомендуется ожидание по условию выражать в коде, эквивалентно м циклу «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);

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

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

Аннулирование потока и ожидание по условию

Ожидание по условию, синхронизированное или нет, является точкой отмены (аннулирования) потока. Другими словами, функции pthread_cond_wait () или pthread_cond_timedwait () представляют собой точки, в которых обнаружен необработанный запрос на отмену. Дело в том, что в этих точках возможно бесконечное ожидание, т.е. какое бы событие ни ожидалось, даже при совершенно корректной программе оно может никогда не произойти; например, входные данные, получения которых ожидает программа, могут быть никогда не отправлены. Сделав же ожидание по условию точкой отмены, поток можно безопасно аннулировать и выполнить соответствующие обработчики даже в случае, если программа «увязнет» в бесконечном ожидании.