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

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

我正在研究一个名为“Ilmiont DDNS Alerter”的简单Python程序。正如标题所示,目的是让您知道动态IP地址何时发生变化。

它通过咨询外部服务器来实现。在Tkinter GUI中,用户可以选择时间频率来更新它。当他们启动更新程序时,我想安排更新功能按用户指定的每x分钟运行一次。我见过sched模块,但似乎只安排了一次。如何在停止之间的间隔内重复检查新IP?

我无法解决如何安排这个问题。此外,当更新程序运行时,GUI在进程完成时无响应。这可能需要几秒钟,尤其是在慢速连接上。据推测线程会克服这个?

python multithreading networking tkinter schedule
3个回答
1
投票

你有两个选择:

  1. 每5(或x)分钟运行一次的循环,以添加到计划中
  2. 或者安排函数在上次完成后x分钟再次运行。

在任何一种情况下,你的cancel按钮都会在某个地方设置一个标志,运行函数应该检查它们的第一个操作。

第一种情况的最大缺点是它将锁定其他代码的执行。更简单的路线肯定是让函数在运行后自行安排。如果您的其他代码需要很长时间,那么线程绝对是您可以调查的选项;我不必自己使用它,但类似下面的代码应该有效:

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()

所以点击'开始',它将每两秒打印一次,加上其他功能将在两者之间运行。您可以随时点击“ACTIVE”以证明界面具有响应性。我希望这是有帮助的?如果你真的反对调用自身的函数,你可能会启动一个只运行无限循环的线程,将事件添加到队列中,但这似乎是一个不必要的复杂问题。

我注意到如果slow_execute函数正在执行大量的数字运算,则线程将不是最佳选择,由于全局解释器锁定的操作,线程主要用于缓慢的I / O.如果您正在等待结果/通信,那应该没问题。


2
投票

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

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

祝好运 !


0
投票

你可以尝试Threading.Timer

请参阅此示例

from threading import Timer

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

它将每分钟打印“Running job_function

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