我正在执行实时数据处理+显示,我每 60 秒访问一次我们的数据库。我不想time.sleep()
每 60 秒等待一次,因为它会取消我的控制权(即 REPL 访问变量,这不是必需的但很好)并冻结 matplotlib 图表。
有替代方案吗?理想情况下,最初将控制权交给用户,然后在 60 秒后拿走控制权,运行一些代码并更新绘图,然后将控制权交还给用户。(当我说控制时,我指的是 REPL 控制)。
有任何想法吗?
我正在执行实时数据处理+显示,我每 60 秒访问一次我们的数据库。我不想time.sleep()
每 60 秒等待一次,因为它会取消我的控制权(即 REPL 访问变量,这不是必需的但很好)并冻结 matplotlib 图表。
有替代方案吗?理想情况下,最初将控制权交给用户,然后在 60 秒后拿走控制权,运行一些代码并更新绘图,然后将控制权交还给用户。(当我说控制时,我指的是 REPL 控制)。
有任何想法吗?
如果您不需要取消用户控制,有一个非常简单的方法可以做到这一点:创建一个threading.Timer
.
你想做的是把函数的“延续”——也就是说,后面的所有东西time.sleep
——移动到一个单独的函数my_function
中,然后像这样安排它:
threading.Timer(60, my_function).start()
并且在 结束时,它使用完全相同的代码行my_function
安排一个新的。Timer
Timer
是一个非常笨重的接口和实现,但它内置在标准库中。您可以在 ActiveState 和 PyPI 上的模块上找到提供更好类的配方,例如,在一个线程上运行多个计时器而不是每个计时器一个线程,让您安排重复调用,这样您就不必自己重新安排等等。但是对于每 60 秒运行一次的东西,我想你可能对Timer
.
需要记住的一件事:如果后台作业需要处理用户在 REPL 中处理的任何相同数据,则可能会出现竞争条件。通常在交互式环境中(尤其是在 Python 中,多亏了 GIL),您可以让用户承担不引起任何竞争的责任。如果没有,您将需要某种同步。
要记住的另一件事:如果您尝试进行 GUI 工作,取决于您使用的 GUI(我相信matplotlib
是可配置的,但默认为tkinter
?),您可能无法从后台线程更新 GUI。
但无论如何,在这种情况下实际上有一个更好的解决方案。GUI 程序有一个在某个线程或其他线程中运行的事件循环,并且几乎每个设计的事件循环都有一种在该线程中调度计时器的方法。对于tkinter
,如果您有root
对象的句柄,只需调用root.after(60000, my_function)
而不是threading.Timer(60, my_function).start()
,它将在与 GUI 相同的线程上运行,并且不会浪费任何不必要的资源。