81 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import asyncio
class Rate:
def __init__(self, hz):
self.interval = 1.0 / hz
self.last_time = time.monotonic()
self.start_time = self.last_time
def sleep(self,print_duration=False):
now = time.monotonic()
sleep_duration = self.interval - (now - self.last_time)
if sleep_duration > 0:
if print_duration:
print(f"睡眠时间: {sleep_duration:.4f}")
time.sleep(sleep_duration)
self.last_time = time.monotonic()
def precise_sleep(self):
# 计算距离下一次休眠的剩余时间
now = time.perf_counter()
elapsed = now - self.last_time
sleep_duration = self.interval - elapsed
# 分成多个小的睡眠周期
while sleep_duration > 0:
# 最大睡眠时间限制在 1ms 以内,避免过多的误差
sleep_time = min(sleep_duration, 0.001) # 最大休眠1ms
time.sleep(sleep_time)
now = time.perf_counter()
elapsed = now - self.last_time
sleep_duration = self.interval - elapsed
self.last_time = time.perf_counter()
async def async_sleep(self):
now = time.monotonic()
sleep_duration = self.interval - (now - self.last_time)
if sleep_duration > 0:
# print(f"睡眠时间: {sleep_duration:.4f} 秒")
await asyncio.sleep(sleep_duration)
self.last_time = time.monotonic()
def remaining(self):
now = time.monotonic()
remaining_time = self.interval - (now - self.last_time)
return max(0.0, remaining_time)
def cycle_time(self):
now = time.monotonic()
cycle_duration = now - self.start_time
self.start_time = now
return cycle_duration
def to_sec(self):
return self.interval
if __name__ == "__main__":
# 示例用法:同步代码
def main_sync():
rate = Rate(2) # 2 赫兹的循环频率每次迭代0.5秒)
for i in range(10):
print(f"同步迭代 {i}")
print(f"剩余时间: {rate.remaining():.4f}")
print(f"上一个循环周期时间: {rate.cycle_time():.4f}")
rate.sleep()
# 示例用法:异步代码
async def main_async():
rate = Rate(2) # 2 赫兹的循环频率每次迭代0.5秒)
for i in range(10):
print(f"异步迭代 {i}")
print(f"剩余时间: {rate.remaining():.4f}")
print(f"上一个循环周期时间: {rate.cycle_time():.4f}")
await rate.async_sleep()
main_sync()
asyncio.run(main_async())