Could you explain the difference between CLOCK_REALTIME
and CLOCK_MONOTONIC
clocks returned by clock_gettime()
on Linux?
Which is a better choice if I need to compute elapsed time between timestamps produced by an external source and the current time?
Lastly, if I have an NTP daemon periodically adjusting system time, how do these adjustments interact with each of CLOCK_REALTIME
and CLOCK_MONOTONIC
?
CLOCK_REALTIME
represents the machine\'s best-guess as to the current wall-clock, time-of-day time. As Ignacio and MarkR say, this means that CLOCK_REALTIME
can jump forwards and backwards as the system time-of-day clock is changed, including by NTP.
CLOCK_MONOTONIC
represents the absolute elapsed wall-clock time since some arbitrary, fixed point in the past. It isn\'t affected by changes in the system time-of-day clock.
If you want to compute the elapsed time between two events observed on the one machine without an intervening reboot, CLOCK_MONOTONIC
is the best option.
Note that on Linux, CLOCK_MONTONIC
does not measure time spent in suspend, although by the POSIX definition it should. You can use the Linux-specific CLOCK_BOOTTIME
for a monotonic clock that keeps running during suspend.
Robert Love\'s book LINUX System Programming 2nd Edition, specifically addresses your question at the beginning of Chapter 11, pg 363:
The important aspect of a monotonic time source is NOT the current
value, but the guarantee that the time source is strictly linearly
increasing, and thus useful for calculating the difference in time
between two samplings
That said, I believe he is assuming the processes are running on the same instance of an OS, so you might want to have a periodic calibration running to be able to estimate drift.
CLOCK_REALTIME
is affected by NTP, and can move forwards and backwards. CLOCK_MONOTONIC
is not, and advances at one tick per tick.
In addition to Ignacio\'s answer, CLOCK_REALTIME
can go up forward in leaps, and occasionally backwards. CLOCK_MONOTONIC
does neither; it just keeps going forwards (although it probably resets at reboot).
A robust app needs to be able to tolerate CLOCK_REALTIME
leaping forwards occasionally (and perhaps backwards very slightly very occasionally, although that is more of an edge-case).
Imagine what happens when you suspend your laptop - CLOCK_REALTIME
jumps forwards following the resume, CLOCK_MONOTONIC
does not. Try it on a VM.
POSIX 7 specifies both at http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html:
CLOCK_REALTIME
:
This clock represents the clock measuring real time for the system. For this clock, the values returned by clock_gettime() and specified by clock_settime() represent the amount of time (in seconds and nanoseconds) since the Epoch.
CLOCK_MONOTONIC
(optional feature):
For this clock, the value returned by clock_gettime() represents the amount of time (in seconds and nanoseconds) since an unspecified point in the past (for example, system start-up time, or the Epoch). This point does not change after system start-up time. he value of the CLOCK_MONOTONIC clock cannot be set via clock_settime().
clock_settime()
gives an important hint: POSIX systems are able to arbitrarily change CLOCK_REALITME
with it, so don\'t rely on it flowing neither continuously nor forward. NTP could be implemented using clock_settime()
, and could only affect CLOCK_REALITME
.
The Linux kernel implementation seems to take boot time as the epoch for CLOCK_MONOTONIC
: Starting point for CLOCK_MONOTONIC