Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

Linux

Linux Problem Overview


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?

Linux Solutions


Solution 1 - Linux

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_MONOTONIC 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.

Solution 2 - Linux

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.

Solution 3 - Linux

CLOCK_REALTIME is affected by NTP, and can move forwards and backwards. CLOCK_MONOTONIC is not, and advances at one tick per tick.

Solution 4 - Linux

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.

Solution 5 - Linux

POSIX 7 quotes

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. The 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_REALTIME.

The Linux kernel implementation seems to take boot time as the epoch for CLOCK_MONOTONIC: https://stackoverflow.com/questions/14726401/starting-point-for-clock-monotonic

Solution 6 - Linux

Sorry, no reputation to add this as a comment. So it goes as an complementary answer.

Depending on how often you will call clock_gettime(), you should keep in mind that only some of the "clocks" are provided by Linux in the VDSO (i.e. do not require a syscall with all the overhead of one -- which only got worse when Linux added the defenses to protect against Spectre-like attacks).

While clock_gettime(CLOCK_MONOTONIC,...), clock_gettime(CLOCK_REALTIME,...), and gettimeofday() are always going to be extremely fast (accelerated by the VDSO), this is not true for, e.g. CLOCK_MONOTONIC_RAW or any of the other POSIX clocks.

This can change with kernel version, and architecture.

Although most programs don't need to pay attention to this, there can be latency spikes in clocks accelerated by the VDSO: if you hit them right when the kernel is updating the shared memory area with the clock counters, it has to wait for the kernel to finish.

Here's the "proof" (GitHub, to keep bots away from kernel.org): https://github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7

Solution 7 - Linux

There's one big difference between CLOCK_REALTIME and MONOTONIC. CLOCK_REALTIME can jump forward or backward according to NTP. By default, NTP allows the clock rate to be speeded up or slowed down by up to 0.05%, but NTP cannot cause the monotonic clock to jump forward or backward.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNPEView Question on Stackoverflow
Solution 1 - LinuxcafView Answer on Stackoverflow
Solution 2 - Linuxuser2548100View Answer on Stackoverflow
Solution 3 - LinuxIgnacio Vazquez-AbramsView Answer on Stackoverflow
Solution 4 - LinuxMarkRView Answer on Stackoverflow
Solution 5 - LinuxCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 6 - LinuxanonymousView Answer on Stackoverflow
Solution 7 - LinuxselcukakarinView Answer on Stackoverflow