Не могли бы вы объяснить разницу между CLOCK_REALTIME
и CLOCK_MONOTONIC
ЧАСЫ возвращаемые clock_gettime()
на Linux?
Какой вариант лучше выбрать, если мне нужно вычислить прошедшее время между временными метками, созданными внешним источником, и текущим временем?
Наконец, если у меня есть демон NTP, периодически меняющий системное время, как эти настройки взаимодействуют с каждым из CLOCK_REALTIME
и CLOCK_MONOTONIC
?
CLOCK_MONOTONIC
ли лучший выбор в этом сценарии? например, Ракетная система ПатриотКнига Роберта Лава, посвященная системному программированию LINUX, 2-е издание , конкретно рассматривает ваш вопрос в начале главы 11, стр. 363:
Тем не менее, я полагаю, что он предполагает, что процессы выполняются в одном и том же экземпляре ОС, поэтому вам может потребоваться периодическая калибровка для оценки дрейфа.
источник
CLOCK_REALTIME
На него влияет NTP, и он может двигаться вперед и назад.CLOCK_MONOTONIC
нет, и продвигается на один тик за тик.источник
System.nanoTime()
используетCLOCK_MONOTONIC
и может измерять продолжительность 1000 нс или меньше. Может быть, вы думаете о системном времени, которое иногда ограничивается миллисекундами?В дополнение к ответу Игнасио ,
CLOCK_REALTIME
может подняться вперед скачком, а иногда и назад.CLOCK_MONOTONIC
не делает ни; он просто продолжает двигаться вперед (хотя, вероятно, он сбрасывается при перезагрузке).Надежное приложение должно быть способно выдерживать
CLOCK_REALTIME
скачкообразный скачок вперед (и, возможно, очень незначительно назад, иногда, хотя это скорее крайний случай).Представьте, что происходит, когда вы подвешиваете свой ноутбук -
CLOCK_REALTIME
прыгает вперед, следуя резюме,CLOCK_MONOTONIC
не делает. Попробуйте это на ВМ.источник
CLOCK_PROCESS_CPUTIME_ID
. Быстрый тест:$ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'
-> 706724.117565279. Это число соответствует времени работы системы в Linux, но стандарт говорит, что это произвольно.CLOCK_MONOTONIC
остановка приостанавливается / возобновляется, соответствует POSIX. Предполагается, что это было время с фиксированной точки в прошлом, но остановка часов из-за приостановки / возобновления ломает это.POSIX 7 цитаты
POSIX 7 указывает оба на http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html :
CLOCK_REALTIME
:CLOCK_MONOTONIC
(дополнительная функция):clock_settime()
дает важный совет: системы POSIX могут произвольно менятьсяCLOCK_REALITME
вместе с ним, поэтому не полагайтесь на то, что он течет ни непрерывно, ни вперед. NTP может быть реализован с использованиемclock_settime()
и может повлиять толькоCLOCK_REALITME
.Реализация ядра Linux, по-видимому, требует времени загрузки в качестве эпохи для
CLOCK_MONOTONIC
: отправной точки для CLOCK_MONOTONICисточник
Извините, нет репутации, чтобы добавить это как комментарий. Так что это идет как дополнительный ответ.
В зависимости от того, как часто вы будете звонить
clock_gettime()
, вы должны иметь в виду, что Linux предоставляет только некоторые из «часов» в VDSO (то есть не требует системного вызова со всеми дополнительными издержками, что только ухудшается, когда добавляется Linux). защита для защиты от атак, подобных призраку).В то время
clock_gettime(CLOCK_MONOTONIC,...)
,clock_gettime(CLOCK_REALTIME,...)
иgettimeofday()
всегда будет очень быстро (ускорен VDSO), это не относится к, например , CLOCK_MONOTONIC_RAW или любой из других POSIX часов.Это может измениться в зависимости от версии ядра и архитектуры.
Хотя большинству программ не нужно обращать на это внимание, в VDSO могут наблюдаться всплески задержек в часах, ускоряемые VDSO: если вы нажмете их правильно, когда ядро обновляет область общей памяти с помощью счетчиков тактовых импульсов, оно должно ждать ядро закончить.
Вот «доказательство» (GitHub, чтобы держать ботов подальше от kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7
источник
CLOCK_REALTIME
: Абсолютное время (например, 07/01/2020)CLOCK_MONOTONIC
: Относительное время (например, 5 секунд или 10 минут назад)источник