运行 每 x 分钟重复执行一次任务

Run task repeatedly every x minutes

我正在开发一个名为 "Ilmiont DDNS Alerter" 的简单 Python 程序。如标题所示,目的是让您知道您的动态 IP 地址何时更改。

它通过咨询外部服务器来完成此操作。在 Tkinter GUI 中,用户可以 select 一个时间频率来更新它。当他们启动更新程序时,我想将更新功能安排为每 x 分钟 运行,如用户指定的那样。我看过 sched 模块,但它似乎只安排一次。如何让它在间隔内重复检查新 IP 直到停止?

我不知道如何安排这个。此外,当更新程序 运行s 时,GUI 在进程完成时变得无响应。这可能需要几秒钟,尤其是在连接速度较慢的情况下。大概线程会克服这个问题?

我认为这与您正在寻找的内容相似,给出的答案也可能适用于您的问题。 Loop socket request every 5 seconds (Python)

答案表明你应该使用一个名为 "after_idle" 的 tkinter 模块,它会安排一个函数,一旦 GUI 不再忙时就会调用它。您还可以使用 .after(time, function) 在再次调用函数之前延迟特定的时间。

祝你好运!

你真的有两个选择:

  1. 一个循环,每 5(或 x)分钟 运行s 添加到计划中

  2. 或将函数安排到 运行 上次完成 x 分钟后再次执行。

在任何一种情况下,您的 cancel 按钮都会在某处设置一个标志,运行ning 函数应该将其作为第一个操作进行检查。

第一种情况的最大缺点是它会锁定其他代码的执行。更简单的方法肯定是让函数在 运行s 之后自行调度。如果您的其他代码需要很长时间,线程绝对是您可以研究的一个选项;我不必自己使用它,但类似于下面的代码应该可以工作:

import threading
import tkinter
import time


class RepeatExecute(object):
    def __init__(self,master,t=2000):
        self.master=master
        self.time=t

    def go(self):
        self.GO = True
        self.call_self()

    def call_self(self):
        if self.GO is True:
            t = self.time
            print(time.time())
            thrd = threading.Thread(target=self.slow_execute)
            thrd.start()
            self.master.after(t,self.call_self)

    def set_time(self,t):
        self.time=t

    def stop(self):
        self.GO = False

    def slow_execute(self):
        time.sleep(1.0)
        if self.GO is True:
            print('Halfway')

    def active(self):
        print('Active')


if __name__=='__main__':
    root =tkinter.Tk()
    RE = RepeatExecute(root,t=2000)
    btn1 = tkinter.Button(root,text='Start',command=RE.go)
    btn1.grid()
    btn2 = tkinter.Button(root,text='Stop',command=RE.stop)
    btn2.grid()
    btn3 = tkinter.Button(root,text='ACTIVE!',command=RE.active)
    btn3.grid()
    root.mainloop()

所以点击'Start',它会每两秒打印一次时间,另外一个函数会在两者之间运行。您可以随时点击 'ACTIVE' 来证明界面是响应式的。我希望这是有帮助的?如果您真的反对函数调用自身,您可能会启动一个线程,该线程只是 运行 一个向队列添加事件的无限循环,但这似乎是一个不必要的复杂化。

我确实注意到,如果 slow_execute 函数正在执行大量 c运行ching,线程将不是最佳选择,线程主要用于慢 I/O 由于到全局解释器锁的动作。如果您正在等待 results/communications.

应该没问题

你可以试试Threading.Timer

看这个例子

from threading import Timer

def job_function():
    Timer(60, job_function).start ()
    print("Running job_funtion")
job_function()

每分钟打印“Running job_function