Разница между CLOCK_REALTIME и CLOCK_MONOTONIC?

Не могли бы вы объяснить разницу между CLOCK_REALTIME и CLOCK_MONOTONIC часами, возвращаемыми clock_gettime() в Linux?

Какой лучший выбор, если мне нужно вычислить прошедшее время между временными метками, создаваемыми внешним источником и текущим временем?

Наконец, если у меня есть демон NTP, периодически настраивающий системное время, как эти корректировки взаимодействуют с каждым из CLOCK_REALTIME и CLOCK_MONOTONIC?

Ответ 1

CLOCK_REALTIME представляет собой машину, которая лучше всего угадывает текущие настенные часы, время суток. Как говорят Ignacio и MarkR, это означает, что CLOCK_REALTIME может перепрыгивать вперед и назад при изменении системного времени суток, в том числе NTP.

CLOCK_MONOTONIC представляет собой абсолютное истекшее время настенных часов с некоторой произвольной неподвижной точки в прошлом. На него не влияют изменения в системном времени суток.

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

Обратите внимание, что в Linux CLOCK_MONTONIC не измеряет время, потраченное на приостановку, хотя по определению POSIX оно должно. Вы можете использовать CLOCK_BOOTTIME для Linux для монотонных часов, которые продолжают работать во время приостановки.

Ответ 2

Роберт Любви Системное программирование LINUX 2nd Edition, в частности, затрагивает ваш вопрос в начале главы 11, стр. 363:

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

Тем не менее, я считаю, что он предполагает, что процессы работают на одном экземпляре ОС, поэтому вы можете иметь периодическую калибровку, чтобы иметь возможность оценить дрейф.

Ответ 3

CLOCK_REALTIME влияет на NTP и может перемещаться вперед и назад. CLOCK_MONOTONIC нет и продвигается на один тик за отметку.

Ответ 4

В дополнение к ответ Ignacio, CLOCK_REALTIME может двигаться вперед в прыжках, а иногда и назад. CLOCK_MONOTONIC нет; он просто продолжает двигаться вперед (хотя он, вероятно, сбрасывается при перезагрузке).

Устойчивое приложение должно быть способно переносить CLOCK_REALTIME время от времени перепрыгивать вперед (и, возможно, назад очень немного очень редко, хотя это скорее крайний случай).

Представьте, что произойдет, когда вы приостановите работу своего ноутбука - CLOCK_REALTIME перескакивает вперед после возобновления, CLOCK_MONOTONIC - нет. Попробуйте на виртуальной машине.

Ответ 5

POSIX 7 цитаты

POSIX 7 указывает оба на http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html:

CLOCK_REALTIME:

Эти часы представляют часы, измеряющие реальное время для системы. Для этих часов значения, возвращаемые функцией clock_gettime() и заданные функцией clock_settime(), представляют количество времени (в секундах и наносекундах) с начала эпохи.

CLOCK_MONOTONIC (дополнительная функция):

Для этих часов значение, возвращаемое функцией clock_gettime(), представляет количество времени (в секундах и наносекундах) с неопределенной точки в прошлом (например, время запуска системы или эпоха). Эта точка не изменяется после запуска системы. Значение часов CLOCK_MONOTONIC не может быть установлено с помощью clock_settime().

clock_settime() дает важный совет: системы POSIX могут произвольно изменять CLOCK_REALITME вместе с ним, поэтому не полагайтесь на то, что он течет ни непрерывно, ни вперед. NTP может быть реализован с использованием clock_settime() и может влиять только на CLOCK_REALITME.

Реализация ядра Linux, похоже, требует времени загрузки в качестве эпохи для CLOCK_MONOTONIC: Начальная точка для CLOCK_MONOTONIC