Так что на самом деле это не порядок выполнения (что наиболее вероятно правильно), а время, которое делает вас несчастными.И в разделе «он переходит непосредственно к 247 до того, как 243-246 закончил», вы имеете в виду «я наблюдал, как он выполняет 247 до того, как истечет время ожидания в 244».Правильно?
Тогда, я подозреваю, что это проблема ложного пробуждения : поток может быть разбужен, даже если никакой другой поток не сигнализировал переменную условия. Спецификация pthread_cond_timedwait()
говорит о том, что «могут произойти ложные пробуждения от функций pthread_cond_timedwait () или pthread_cond_wait ()».
Обычно переменная условия связана с определенным событием вприложение, и поток, ожидающий условную переменную, фактически ожидает сигнала от другого потока о том, что произошло интересующее событие.Если у вас нет события и вы просто хотите подождать определенное время, на самом деле более подходящими являются другие способы, такие как usleep()
или таймеры , за исключением случаев, когда вам также требуется точка отмены pthread.
ДОБАВЛЕНО: Поскольку вы, кажется, довольны usleep()
и только спросили, почему pthread_cond_timedwait()
не работает, как вы ожидали, я решил не публиковать код.Если вам это нужно, вы можете использовать ответ @ Hasturkun.
ADDED-2: вывод в комментариях ниже (полученный после применения решения Hasturkun) предполагает, что ожидающий поток не завершает работуцикл, который, вероятно, означает, что pthread_cond_timedwait()
возвращает что-то отличное от ETIMEDOUT.Вы видели комментарий @nos к вашему сообщению (я установил количество наносек для вычитания):
Убедитесь (now.tv_usec * 1000) + lt_leak_start_nsec;не переполняетсяВы можете установить tv_nsec только на максимум 999999999, если выражение больше этого, вы должны вычесть 1000000000 из tv_nsec и увеличить tv_sec на 1. Если ваш timeToWaitPtr содержит недопустимый tv_nsec (больше, чем 999999999), pthread_cond_timedwait потерпит неудачу (вы должны проверитьего возвращаемое значение тоже.) - nos 28 апреля в 19: 04
В этом случае pthread_cond_timedwait()
будет многократно возвращать EINVAL
и никогда не выйдет из цикла.Лучше настроить время ожидания перед входом в цикл ожидания, хотя это также можно сделать в ответ на EINVAL
.
ADDED-3: Теперь после того, как вы изменили код в своем вопросе, чтобы передатьТайм-аут без добавления к текущему времени, у него есть другая проблема.Как указано в спецификации , время ожидания для pthread_cond_timedwait()
является абсолютным, а не относительным;поэтому, когда вы передаете что-то вроде 3 секунд в качестве тайм-аута, оно интерпретируется как «3 секунды с момента отсчета системного времени».Этот момент почти наверняка пропущен некоторое время, и поэтому pthread_cond_timedwait()
немедленно возвращается.
Я бы порекомендовал вам внимательно прочитать спецификацию (включая обоснование), чтобы лучше понять, как эта функция должна использоваться.