What is the use of CLOCK_REALTIME?
Asked Answered
D

1

12

I am reading about the difference between CLOCK_REALTIME and CLOCK_MONOTONIC

Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

The CLOCK_REALTIME has discontinuities in time, can jump forwards as well as backwards: is that a bug in this clock? How could a clock that gives inconsistent time be reliable?

Dyslogia answered 27/1, 2017 at 12:39 Comment(18)
Daylight saving time is an example of wall clock time that may jump forwards and backwards. Also note that that answer clearly states it's the system's guess – and when it determines a previous guess was off, it guesses again.Rumple
What does mean a guess? The system guesses the time = determines the time with some ns of errorDyslogia
Depends on what you need it for and what you propose to do with it, sometimes, it's useful to have a timestamp (think logging), or maybe you want to timestamp some objects (creation, completion of transaction etc.) Where it's useful to know the time of something. NOTE: this in no way implies suitability for performance measurement...Fenderson
How does a computer guess the time? It checks its watch. Or maybe it asks on the Internet. It's still a guess because the Internet may be slower than usual. Anyway, it's not, like, you know, it literally has to guess.Rumple
Ok, so then based on the nature of the application we can decide to use CLOCK_MONOTONIC or CLOCK_REALTIME. But for measuring the elapsed time there is no difference between these two clocks ?Dyslogia
@Bionix1441, that's the whole point, each clock type serves a different purpose, the monotonic clock is good for measuring elapsed time (think - how long did something take?), the realtime clock is useful as an indicator of time (think when did something happen?) The realtime clock (due to it's design) is unsuitable for measuring elapsed time (as it can go backwards and forwards.)Fenderson
@Fenderson Now I understand thank you, from the spec only it was not clear to me what the difference was.Dyslogia
@RadLexus Daylight savings time is not an example of something that could make CLOCK_REALTIME jump forwards or backwards,Tris
@SteveSummit: I think that its very definition says it is. I look at my wall clock, and it's 02:58. Five minutes later, I look again and now its says 02:03 -- DST kicked in and adjusted it. My Mac sets the time automatically, and so when I would use wall clock time to measure how long something took, it'd tell me "-55 minutes".Rumple
@RadLexus: No, the state of the clock doesn't account for timezones (inc. DST); only when its state is converted into a human-readable form is a timezone potentially applied. The timezone is an extra "layer" on top of that so that's why you see it "jump" on your GUI. But CLOCK_REALTIME itself does not jump when the timezone changes (or DST comes/goes).Jovitajovitah
@RadLexus: "Or maybe it asks on the Internet. It's still a guess because the Internet may be slower than usual" That's false, too. NTP is designed to account for transmission latency; that's why we use NTP instead of just wgetting a timestamp from the web.Jovitajovitah
@LightnessRacesinOrbit Actually, though not strictly accurate, the notion that NTP "asks on the internet, which might be slower than usual" isn't too far off the mark, and it gave me a grin. NTP is good, but it's not perfect, and sometimes it does give you wrong answers. (And don't get me started about leap seconds.)Tris
@LRiO: two very good points - I realize I got the wrong idea about what "wall time" was to represent.Rumple
@SteveSummit: I do prefer a proper board with an oscillator on it who's steered by PTP (traceable to real UTC) hiding behind a few PLLs ;) And NTP with leap seconds you say? Tell me about it!Jovitajovitah
@RadLexus Sounds like you get this now, but for anyone else who is wondering: human-readable time jumps at DST changeovers, but CLOCK_REALTIME (like the Unix/Posix time it's based on) does not. CLOCK_REALTIME is UTC, without time zones or DST. It gets converted to human-readable time later, and that's where the time zones and DST offsets are introduced.Tris
@LightnessRacesinOrbit Like I said, don't get me started! All the documentation says that ntp (unlike Posix) handles leap seconds properly, but I was watching it on that special recent Sunday, too, and I didn't see it doing what I expected it to do, either. (But kudos to you for trying to test. Me, I'd like to set up a public NTP server that can give you a real simulated leap second whenever you want, but this isn't the place to discuss it.)Tris
@Steve: Alas we wouldn't be able to use it anyway (closed networks). FWIW our NTP servers and clients did appear to behave properly on the night of the 31st.Jovitajovitah
Leapseconds: Current state is there will be no leap seconds until 2035, and there may be no leap seconds until UTC and POSIX time diverge from astronomical time by one minute. I assume in 10 years we will switch to astronomical time (UT1) for normal use, and TAI (atomic time, currently UTC + 31) with no leap seconds if you need true nanosecond precision with 1 second in 100 million years.Ascocarp
T
27

Despite its imperfections, CLOCK_REALTIME should be the system's best estimate of the current UTC or civil time. It's the basis for the system's ability to display the same time you'd see if you looked at your watch, or a clock on the wall, or your cell phone, or listened to a time broadcast on a radio station, etc. (The display does involve a conversion from UTC to local time; more on this later.)

But if CLOCK_REALTIME is going to match the UTC time out there in the real world, there are at least two pretty significant issues:

  1. What if someone accidentally sets the clock on your computer wrong? They're going to have to fix it, and the fix might involve a time jump. Pretty much no way around that, especially if the error is large (like, hours or days).
  2. Most computers unfortunately have no way of representing leap seconds. Therefore, when there's a leap second out in the real world, most computer clocks have to jump a little.

So when you read that CLOCK_REALTIME might have discontinuities, might jump forwards as well as backwards, that's not a bug, it's a feature: CLOCK_REALTIME must have those possibilities, if it's to cope with the real world with leap seconds and occasionally-wrong clocks.

So if you're writing code which is supposed to work with times matching those in the real world, CLOCK_REALTIME is what you want, warts and all. Ideally, though, you'll write your code in such a way that it behaves reasonably gracefully (does not crash or do something bizarre) if, once in a while, the system clock jumps forwards or backwards for some reason.

As you probably know from the other question you referenced, CLOCK_MONOTONIC is guaranteed to always step forward at exactly one second per second, with no jumps or discontinuities, but the absolute value of the clock doesn't mean much. If the CLOCK_MONOTONIC value is 13:05, that doesn't mean it's just after one in the afternoon, it typically means that the computer has been up and running for 13 hours and 5 minutes.

So if all you're interested in is relative times, CLOCK_MONOTONIC is fine. In particular, if you want to time how long something took, by subtracting the start time from the end time, it's preferable to use CLOCK_MONOTONIC values for this, since they won't give you a wrong answer if there was some kind of a time jump (that would have affected CLOCK_REALTIME) in between.

Or, in summary, as people said in the comments thread, CLOCK_REALTIME is what you need for absolute time, while CLOCK_MONOTONIC is better for relative time.

Now, a few more points.

As mentioned, CLOCK_REALTIME is not quite "wall time", because it actually deals in UTC. It uses the famous (infamous?) Unix/Posix representation of UTC seconds since 1970. For example, a CLOCK_REALTIME value of 1457852399 translates to 06:59:59 UTC on March 13, 2016. Where I live, five hours west of Greenwich, that corresponds to 01:59:59 local time. But one second later was not 2:00 in the morning for me! In fact, 1457852399 + 1 = 1457852400 corresponds to 03:00:00 Eastern time, because that's when Daylight Saving Time kicked in here.

I suggested that if your clock was wrong, a time jump was pretty much the only way to fix it, but that's not quite true. If your clock is only slightly off, it's possible to correct it by "slewing" the time gradually (by changing the clock frequency slightly) so that after a few minutes or hours it will have drifted to the correct time without a jump. That's what NTP tries to do, although depending on its configuration it may only be willing to do that for errors that are pretty small.

I said that CLOCK_MONOTONIC was typically the time the computer has been up and running. That's not guaranteed by the standard; all the standard says is that CLOCK_MONOTONIC counts time since some arbitrary timepoint. On systems that do implement CLOCK_MONOTONIC as the time the system has been up, there can be two interpretations: is it time since boot, or the time the system has been up and running (that is, minus any time it was asleep or suspended)? On many systems, there's yet another clock, CLOCK_BOOTTIME, that counts time since boot (whether up or suspended), while CLOCK_MONOTONIC counts only time the system was up and running.

I said, "CLOCK_MONOTONIC is guaranteed to always step forward at exactly one second per second", but that may not be strictly correct, either. If your computer is in the middle of a time-slewing operation, trying to gradually correct an absolute time error, it may actually be the case that CLOCK_MONOTONIC is temporarily stepping at 1.001 seconds per second, or 0.999 seconds per second, or something like that. The discrepancy will usually be quite small, but in case it matters to you, some systems have yet other clock types you can use, such as CLOCK_MONOTONIC_RAW, that are supposed to be free of such perturbations.

Finally, if you want to track proper time, and you want to avoid jumps or discontinuities at leap seconds, you've got a problem, because of the poor handling of leap seconds in traditional Unix/Linux (and Windows, and all other) computer systems. Under recent (4.x?) Linux kernels, there's a CLOCK_TAI which may help. Some experimental systems may implement yet another clock, CLOCK_UTC, which handles UTC time with leap seconds properly. Both of those have some other costs, though, and you'd have to really know what you were doing to use them effectively, at least with today's level of support. See the LEAPSECS mailing list for more information.

Tris answered 27/1, 2017 at 14:1 Comment(7)
Superb answer. Covers all the bases in an easy-to-digest manner.Jovitajovitah
"That's what NTP tries to do, although it turns out it's willing to do that only for errors that are quite small (like, less than a second, I think)." That's entirely configurable in your NTP clientJovitajovitah
@LightnessRacesinOrbit That depends on your NTP client, I think. I have it on good authority that the reference implementation will slew only if the error is less than 128 milliseconds, and there's no way to reconfigure this value.Tris
@LightnessRacesinOrbit But I think other ntp implementations are less fussy, so I tweaked the wording.Tris
@SteveSummit Awsome answer. Thank youDyslogia
FWIW, I don't believe that the "time the system has been up and running" interpretation of CLOCK_MONOTONIC is in conformance with POSIX: the time since an arbitrary point in the past does not stop counting just because the system is asleep.Tardy
On my Mac and iPhone, experimentally CLOCK_MONOTONIC is nanoseconds since boot, continuing while the computer sleeps, and CLOCK_UPTIME_RAW is nanoseconds since boot, stopping when the computer sleeps. Both don't change when I change the clock on my computer or phone to next year, actually that changes the boot time! There seems to be a few seconds difference, probably some disagreement when exactly "boot + 0 seconds" is.Ascocarp

© 2022 - 2024 — McMap. All rights reserved.