以毫秒精度在特定时间运行函数

问题描述 投票:0回答:2

我尝试在特定时间以毫秒精度运行一个函数,但我使用的每种方法都有一些延迟,甚至不是恒定的延迟(例如,它在 30 到 90 毫秒之间变化)。

这是我的代码之一

tt = datetime(2021, 8, 22, 3, 17, 00) #desired time
time.sleep((time.mktime(tt.timetuple())) - time.time())
print(datetime.now().strftime('%H:%M:%S.%f')[:-3])

其输出是:

03:17:00.038

如您所见,它有 0.038 秒的延迟。我也尝试过

pause
,结果是一样的。 有没有办法消除这种延迟或使其保持不变?

python scheduled-tasks milliseconds
2个回答
3
投票

这就是非实时操作系统的本质。如果你要求 3ms 的延迟,为了准确地实现这一点,操作系统必须从现在起 3ms 后获得一个中断来唤醒你。他们不这样做。相反,有一个定期的计时器中断,在此期间调度程序重新评估所有正在运行的线程以查看下一个应该运行的线程。在评估过程中,它会检查是否有任何计时器已过期。

计划间隔因操作系统而异。在 Windows 上,该时间为 16 毫秒。在Linux上,情况稍微复杂一些,有几种不同的调度算法;历史上为 100ms,可向下调整。

time.sleep
之类的东西只能保证您至少会按照您的要求睡觉。在 Windows 上,如果您请求 10 毫秒,您将休眠至少 16 毫秒,因为直到调度程序间隔才会检查您的计时器。

就是这样。你需要使用它。


0
投票

就像提到的 time.sleep 设置了最短时间,但可能更多地取决于操作系统调度程序实现的其他内容(哎呀,在 Linux 上,您可以在多个调度程序之间进行选择)和正在执行的操作以及您正在运行的其他程序。如果计时器分辨率为 1 毫秒,您可以在 20 毫秒或更长时间后重新获得控制权,谁知道它甚至可能在请求的时间之前返回控制权

但是与之前所说的不同,从 Win 7 开始,默认的调度间隔是 1 毫秒。您本来可以要求这个间隔,但现在您甚至不必这样做

Python 中最准确的计时器是 time.perf_counter_ns。如果您使用浮动变量,一小时后分辨率会超过 1 毫秒。第二准确的是 time.perf_counter

运行函数的最准确方法是使用繁忙循环,但这会最大化 CPU 核心使用率并浪费能源。第二好的是线程上的 wait() ,但目前 Python 只提供浮点版本,但如果您使用 perf_counter_ns() 跟踪计时器,您应该能够尽可能准确地测量已经过去了多少时间并可以调整传递给 wait() 的值

我知道这是一个老问题,但只是想纠正新 Windows 版本上的默认刻度间隔,因为知道这会节省我几个小时的时间去修补我不再需要修复的东西

© www.soinside.com 2019 - 2024. All rights reserved.