2

I would like to use a monotonic timer (in the sense of threading.Timer) in Python (ideally in 2.7, 3.6 and 3.8, and at least on Linux).

Python 2.7 uses time.sleep() in the Timer, while Python 3 uses threading.Event.wait(), which boils down to sem_clockwait(CLOCK_MONOTONIC) on systems with GLibC 2.30+/Python 3.11+ and sem_timedwait() on older systems. sem_timedwait() uses non-monotonic clock.

time.sleep() itself uses select() before Python 3.11, which uses the non-monotonic clock, and clock_nanosleep(CLOCK_MONOTONIC) since Python 3.11.

So the only systems where threading.Timer acts as a monotonic timer are Python 3.11+ on GlibC 2.30+ system.

Is there a way to create a platform-agnostic monotonic timer (or at least a sleep function) without busy-waiting?

NB: We have a system that actually suffers several time jumps on each power on. That's why a simple time.sleep() is not a good solution for us. If the time jump went too far back, the sleep would never end.

Martin Pecka
  • 2,953
  • 1
  • 31
  • 40
  • Hmm, so it seems `time.sleep()` actually always "sleeps in monotonic time". There is nothing in the docs regarding this behavior, but practical experiments show that time jumps do not affect the duration of the sleep. I test it with a Python script that has `time.sleep(10)` and when the sleep is active, I run `date && sudo date +%T -s "$(date +%T --date '-5 seconds')" && date` in console. The actual duration of the sleep is always 10 seconds. I've found one post that supports this experimental finding, although without any explanation: https://stackoverflow.com/a/427877/1076564. – Martin Pecka Oct 06 '22 at 10:28

0 Answers0