Python:为什么事件调度程序总是漂移,有没有办法解决这个问题?



我想在 tkinter GUI 中使用调度程序作为秒表。 我不确定这是否比使用后台线程更好,但我读到你不应该停止线程,而我想不断地启动和停止一个函数。

我在 Python 2.7 中做了一小段代码来测试调度程序,它似乎立即开始漂移。 我希望它每秒增加一个计数器,但一分钟后我偏离了两秒(62 秒过去了,而不是 60 秒(。

这台机器有关系吗? 我的代码有问题吗? 我应该使用另一个库吗?

import sched, time
class Scheduler_Test:
def __init__(self):
self.counter = 0
self.time_increment = 1.0
self.end_time = 0.0
self.s = sched.scheduler(time.time, time.sleep)
self.start_time = time.time()
self.s.enter(self.time_increment, 1, self.do_something, (self.s,))
self.s.run() # run the event scheduler
#Simple test of printing out the computer time (sec) and count
def do_something(self, random_kwarg): 
print "Time (sec):",time.time(),", count:", self.counter
self.event = self.s.enter(self.time_increment, 1, self.do_something, (random_kwarg,))
self.counter = self.counter + 1
Test = Scheduler_Test()

如果您的目标是跟上长距离的实际时间,切勿使用延迟。

总会有延迟,最终你会超时,原因是 - 事件启动和新事件调度之间的 CPU 工作不为零,而且您始终具有任务优先级。

因此,如果您想延迟 — 使用带有"run_after"接口的接口(在这种情况下sched.enter(。如果你想安排事情——使用"run_at"(在你的情况下.enterabs(。顺便说一句,考虑到你在 python 中只有一个进程,你仍然可以"迟到",但这不是你能影响的事情。

旁注:您很少想重新定义调度程序计时器,默认值很好,它使用time.monotonic回退到time.time。如果您的代码将达到现实世界的使用,单调将使您免于意外的痛苦。

使用time.time来实际计时。您可以使用 tkinter 的时钟更新用户界面,但将其更新为启动计时器时的时间增量值。

我使用基于 tkinter 的 PySimpleGUI 制作了一个类似的应用程序。 我做时机的方式是这样的...伪代码遵循,因为我正在使用包装器来执行这些功能....

start_time = int(round(time.time() * 100))
while True:
# use timer using tkinter's 'after' method
# tkroot.after(timeout, alarmcallback)  (Pseudocode)
# tkroot.mainloop()
#     in the alarm callback I called quit   tkroot.quit()
# Then I'm back in my code....
current_time = int(round(time.time() * 100)) - start_time
# Update the GUI with current_time

相关内容

最新更新