我正在执行实时数据处理 + 显示,我每 60 秒访问一次我们的数据库。我不想使用 time.sleep()
每 60 秒等待一次,因为它会从我手中移除控制权(即 REPL 对变量的访问,这不是必需的但很好)并卡住 matplotlib 图表.
有替代方案吗?理想情况下,最初将控制权交给用户,60 秒后,将控制权拿走,运行一些代码,更新绘图,然后将控制权交还给用户。 (当我说控制时,我指的是 REPL 控制)。
有什么想法吗?
最佳答案
如果您不需要取消用户控制,有一个非常简单的方法:创建一个 threading.Timer
.
您想要做的是获取函数的“延续”——即 time.sleep
之后的所有内容——并将其移至单独的函数 my_function
,然后像这样安排它:
threading.Timer(60, my_function).start()
在 my_function
的末尾,它使用完全相同的代码行安排了一个新的 Timer
。
Timer
是一个非常笨拙的接口(interface)和实现,但它内置于 stdlib 中。您可以在 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 在同一个线程上运行,不会浪费任何不必要的资源。
关于python - 替代 python 的 time.sleep(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15167334/