Repository navigation
Allow sleeping until an absolute time #101558
Description
Activity
- addedtype-featureA feature request or enhancementA feature request or enhancement
on Feb 4, 2023 - added a commit that references this issue
on Feb 4, 2023 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Feb 4, 2023 Worth pointing out that I would love to have the equivalent functions like
asyncio.sleep_until. Not sure if there's any other sleepers to look for.Reacted by HannesI checked the implementation, and
loop.time()is justtime.monotonic(), and the loop is apparently implemented withselect()(fromselectorsorIocpProactoron Windows). I'm not an expert on this but it seems like it might be fairly complicated to implement on a low level, so perhaps in that case it would need to be implemented at a higher level.- added a commit that references this issue
on Feb 11, 2023 Additional arguments for this feature suggestion provided here: #101559 (comment)
- added a commit that references this issue
on Feb 12, 2023 I think that for
asyncioit's possible to use whatasyncio.sleepalready uses underneath. On the first call, an estimate ofloop.time()could be made in absolute time, and every subsequent call is relative to that time by sleeping untilloop.time() + (timestamp - abs_loop_time), calling whatasyncio.sleepuses. This prevents accumulated inaccuracies if multipleasyncio.sleep(seconds)calls are made instead of using multipleasyncio.sleep_until(timestamp).I still don't know of an async equivalent of the system call
clock_nanosleep- and this system function is the main reason I raised this issue. But perhapsloop.call_atcan be used in the emulation for asyncio.I'd love to see the PR attached here merged. To implement a periodic task in a Python loop, one is currently forced to do a racy subtraction with the current time. The pull request attached to this proposal fixes that.
To print 'A' at 100hz, one might naively write:
while True: print('A') time.sleep(0.01)...but of course, that's not really going to yield a coherent 100hz. There are many applications where that matters, such as sampling a sensor to produce timeseries data.
If you actually care, you're forced to do something like this:
p = time.time() while True: print('A') time.sleep(time.time() - p + 0.01) p = time.time()...but that's inherently racy. If this proposal is implemented, that loop could become:
p = time.time() while True: print('A') time.sleep_until(p + 0.01) p += 0.01...which both simplifies the code, and eliminates the race condition. On platforms where there isn't support for TIMER_ABSTIME, it could fall back to the racy subtraction (which is what the user would've done anyway).
Reacted by Shang Chi Wu, Harsh Maheshwari, Alexey Shokov and xtorpganssle's comment sums up the current state here: #101559 (comment)
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsNo status
I propose a version of
time.sleep()that allows for the specification of absolute times.Python 3.11 added the use of
clock_nanosleepintime.sleep()(#28111), and both it and Windows'SetWaitableTimerExallow for the specification of absolute times. This can be useful for writing simple loops that trigger at an interval that is tied to wall-clock time, which has many applications: triggering taking of measurements, pictures, checking status, sending messages, ...With
time.sleep(), one has to emulate this by sayingtime.sleep(deadline - time.time()), whichpysleepthen calculates back into an absolute time internally, which adds inaccuracy.I will be submitting a pull request shortly that modifies
pysleepto give it an "absolute" argument and adds atime.sleep_until()function.Linked PRs