ссылка, которую я использую объясняет два следующим образом:
wait_for
«блокирует текущий поток до тех пор, пока переменная условия не будет разбужена или по истечении заданного времени ожидания»
wait_until
«блокирует текущий поток до тех пор, пока переменная условия не будет разбужена или пока не будет достигнут определенный момент времени»
В чем разница? Будет wait_until
вращаться так, чтобы поток мог продолжать точно (более или менее), когда он сигнализируется, тогда как wait_for
просто добавляет поток обратно в планирование в этот момент?
Разница в том, как отображается продолжительность ожидания: wait_for
занимает относительное время («подождите до 10 секунд»), тогда как wait_until
занимает абсолютное время («подождите до 12:00 30 октября 2012 г.»).
Сравните объявления параметров времени:
// wait_for:
const std::chrono::duration<Rep, Period>& rel_time
// wait_until:
const std::chrono::time_point<Clock, Duration>& abs_time
Ваш вопрос и другие ответы повторили разницу; тот wait_for
ждет указанное количество времени и wait_until
ждет до указанного момента времени, но последствия не прописаны.
time_point
имеет ассоциированные часы, и эти часы используются для определения того, наступило ли подходящее время. Это означает, что настройки часов учитываются wait_until
функция. wait_until(..., system_clock::now() + std::chrono::seconds(10))
может закончиться ожиданием часа и 10 секунд, если часы отрегулированы на час раньше времени ожидания.
Продолжительность не имеет никаких связанных часов и, следовательно, wait_for
выбирает свои часы Стандарт определяет, что он использует std :: stable_clock, который не может быть скорректирован и продвигается с постоянной скоростью относительно реального времени. Это означает, что wait_for
будет ждать указанное время независимо от каких-либо настроек, сделанных для любых часов. wait_for(..., std::chrono::seconds(10))
гарантированно подождет 10 секунд (+ некоторое время для работы реализации и для планирования вопросов).
Там нет никакой разницы в отношении вращения и сна нить; как wait_for
указано вести себя так, как будто он вызвал wait_until
с steady_clock::now() + duration
,
Вот часть стандарта, где это прописано:
2 Реализации обязательно имеют некоторую задержку в возврате
из тайм-аута. Любые издержки в ответе на прерывание, возврат функции,
и планирование вызывает задержку «качества реализации», выраженную
как продолжительность Dя. В идеале эта задержка была бы равна нулю.
Кроме того, любое соперничество за ресурсы процессора и памяти вызывает
Задержка «качества управления», выраженная как продолжительность Dм.
Длительность задержки может варьироваться от времени до времени ожидания, но во всех случаях
короче лучше.3 Функции-члены, чьи имена заканчиваются на
_for
принять
аргумент, который указывает продолжительность. Эти функции производят относительные
тайм-ауты. Реализации должны использовать устойчивые часы для измерения времени
для этих функций. Учитывая аргумент продолжительности DT,
продолжительность тайм-аута в реальном времени DT + Dя + Dм.4 Функции-члены, чьи имена заканчиваются на
_until
принять
аргумент, который указывает момент времени. Эти функции производят абсолютные
тайм-ауты. Реализации должны использовать часы, указанные во времени
указать, чтобы измерить время для этих функций. Учитывая время часов
аргумент СT, момент времени возврата из тайм-аута должен быть
СT + Dя + Dм когда часы не настроены во время тайм-аута. Если
часы настроены на время С во время тайм-аута, поведение
должно быть следующим:
— если С > СT, функция ожидания должна проснуться
как можно скорее, т.е. С + Dя + Dм, так как тайм-аут уже
довольный. [ Замечания: Эта спецификация может привести к общей продолжительности
ожидание уменьшается при измерении на фоне устойчивых часов. —Конечная записка
]— если С <знак равно СT, функция ожидания не должна превышать время ожидания
Clock::now()
возвращает время СN > = СT, то есть просыпаться в СT + Dя + Dм. [
Замечания: Когда часы отрегулированы назад, эта спецификация может
в результате общая продолжительность ожидания увеличивается при измерении
против устойчивых часов. Когда часы настроены вперед, это
спецификация может привести к уменьшению общей продолжительности ожидания
по сравнению с устойчивыми часами. —Конечная записка ]Реализация
должен вернуться с такого тайм-аута в любой момент от указанного времени
выше времени, которое будет возвращаться из относительного таймаута
на разницу между СT и момент времени звонка на
_until
функция. [ Замечания: Реализации должны уменьшить продолжительность ожидания, когда часы настроены вперед. —Конечная записка ]
wait_for
будет ждать определенное количество времени. Например, он будет ждать две секунды.wait_until
будет ждать, пока не пройдет какое-то время. Например, будет ждать до 23 июля 2013 года 11:22:34 вечера. достигается на часах.Вот одно важное различие в их использовании, как объяснено в Энтони Уильямсе книга:
Рассмотрите этот пример, где переменная условия ожидается с тайм-аутом:
std::condition_variable cv;
bool done;
std::mutex m;
bool wait_loop()
{
auto const timeout= std::chrono::steady_clock::now()+
std::chrono::milliseconds(500);
std::unique_lock<std::mutex> lk(m);
while(!done)
{
if(cv.wait_until(lk,timeout)==std::cv_status::timeout)
break;
}
return done;
}
Это рекомендуемый способ ожидания условных переменных с
ограничение по времени, если вы не передаете предикат ожидания. Сюда,
общая длина петли ограниченный. Как вы видели в разделе
4.1.1, вам необходимо выполнить цикл при использовании условных переменных, если вы не передали предикат, чтобы справиться с ложными пробуждениями. Если вы используете
wait_for()
в цикле, вы можете ждать почти всю длину
времени до ложного следа, и в следующий раз через ожидание
время начинается снова. Это может повторяться любое количество раз, делая
общее время ожидания неограниченный.
ИМО, это один из таких сценариев, где wait_for
не может заменить wait_until
так легко, из-за его природы сброса.