Можно задать таймаут одного из двух видов: _for
, а принимающие абсолютный таймаут — словом _until
.
Например, в классе std::condition_variable
есть по два перегруженных варианта функций-членов wait_for()
и wait_until()
, соответствующие двум вариантам wait()
— первый ждет поступления сигнала или истечения таймаута или ложного пробуждения, второй проверяет при пробуждении переданный предикат и возвращает управление, только если предикат равен true
(и условной переменной поступил сигнал) или истек таймаут.
Прежде чем переходить к детальному обсуждению функций с таймаутами, рассмотрим, как в С++ задается время, и начнем с часов.
4.3.1. Часы
С точки зрения стандартной библиотеки С++, часы — это источник сведений о времени. Точнее, класс часов должен предоставлять четыре элемента информации:
• текущее время
• тип значения для представления времени, полученного от часов;
• величина такта часов;
• признак равномерного хода времени, такие часы называются
Получить от часов текущее время можно с помощью статической функции-члена now()
; например, функция std::chrono::system_clock::now()
возвращает текущее время по системным часам. Тип точки во времени для конкретного класса часов определяется с помощью члена typedef time_point
, поэтому значение, возвращаемое функцией some_clock::now()
имеет тип some_clock::time_point
.
Тактовый период часов задается в виде числа долей секунды, которое определяется членом класса typedef period
; например, если часы тикают 25 раз в секунду, то член period
будет определён как std::ratio<1, 25>
, тогда как в часах, тикающих один раз в 2,5 секунды, член period
определён как std::ratio<5, 2>
. Если тактовый период не известен до начала выполнения программы или может изменяться во время работы, то period
можно определить как средний период, наименьший период или любое другое значение, которое сочтет нужным автор библиотеки. Нет гарантии, что тактовый период, наблюдаемый в любом конкретном прогоне программы, соответствует периоду, определённому с помощью члена period.
Если часы period
или нет) и is_steady
класса часов равен true
, если часы стабильны, и false
в противном случае. Как правило, часы std::chrono::system_clock
нестабильны, потому что их можно подвести, даже если такое подведение производится автоматически, чтобы учесть локальный дрейф. Из-за подведения более позднее обращение к now()
может вернуть значение, меньшее, чем более раннее, а это нарушение требования к равномерному ходу часов. Как мы скоро увидим, стабильность важна для вычислений с таймаутами, поэтому в стандартной библиотеке С++ имеется класс стабильных часов — std::chrono::steady_clock
. Помимо него, стандартная библиотека содержит класс std::chrono::system_clock
(уже упоминавшийся выше), который представляет системный генератор «реального времени» и имеет функции для преобразования моментов времени в тип time_t
и обратно, и класс std::chrono::high_resolution_clock
, который представляет наименьший возможный тактовый период (и, следовательно, максимально возможное разрешение). Может статься, что этот тип на самом деле является псевдонимом typedef
какого-то другого класса часов. Все эти классы определены в заголовке
наряду с прочими средствами работы со временем.
Чуть ниже мы рассмотрим представления моментов времени, но сначала познакомимся с представлением интервалов.
4.3.2. Временные интервалы