GeezerVison is showing github.com — Allow sleeping until an absolute time · Issue #101558 · python/cpython
Allow sleeping until an absolute time #101558DescriptionI propose a version of time.sleep() that allows for the specification of absolute times.
Python 3.11 added the use of clock_nanosleep in time.sleep() (#28111), and both it and Windows' SetWaitableTimerEx allow 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 saying time.sleep(deadline - time.time()), which pysleep then calculates back into an absolute time internally, which adds inaccuracy.
I will be submitting a pull request shortly that modifies pysleep to give it an "absolute" argument and adds a time.sleep_until() function.
Linked PRs
Reacted by Oleg Iarygin, Sanyam Khurana, Sam Mason, Roman Donchenko, Shang Chi Wu, Nadav Har'El, Jan Larres and Tadhg McDonald-Jensen ActivitySimpleArt commented on Feb 5, 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. haukex commented on Feb 6, 2023 ContributorAuthor More actions I checked the implementation, and loop.time() is just time.monotonic(), and the loop is apparently implemented with select() (from selectors or IocpProactor on 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. haukex commented on Feb 12, 2023 ContributorAuthor More actions SimpleArt commented on Mar 15, 2023 I think that for asyncio it's possible to use what asyncio.sleep already uses underneath. On the first call, an estimate of loop.time() could be made in absolute time, and every subsequent call is relative to that time by sleeping until loop.time() + (timestamp - abs_loop_time), calling what asyncio.sleep uses. This prevents accumulated inaccuracies if multiple asyncio.sleep(seconds) calls are made instead of using multiple asyncio.sleep_until(timestamp). haukex commented on Mar 18, 2023 ContributorAuthor More actions 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 perhaps loop.call_at can be used in the emulation for asyncio. jcalvinowens commented on Jan 22, 2024 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 xtor hauntsaninja commented on Sep 17, 2024
MetadataMetadataStatusShow more project fields
DevelopmentNo branches or pull requestsIssue actions
|