1

我有简单的 PyGTK 应用程序。由于我必须运行多个定期任务来获取一些数据并刷新 GUI,所以我扩展了 Thread 如下:

class MyThread(threading.Thread):        
    def __init__(self):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.event = threading.Event()
        self.event.set()

    def run(self):
        while self.event.is_set():
            timer = threading.Timer(60, self._run)   
            timer.start()
            timer.join()

    def cancel(self):
        self.event.clear()

    def _run(self):
        gtk.threads_enter()
        # do what need to be done, fetch data, update GUI
        gtk.threads_leave()

我在应用程序引导程序上启动线程,将它们保存在某个列表中并在退出前取消它们。这非常完美。

但是现在我想添加刷新按钮,这将强制其中一个线程立即运行,而不是等待一段时间才能运行,如果当前没有运行的话。

我尝试通过将 bool var 添加到 MyThread 来指示线程是否正在运行(在 _run 之前设置,完成时重置),然后如果未运行则只调用 MyThread._run() 来做到这一点,但这会导致我的应用程序成为无响应和 _run 任务永远不会完成执行。

我不确定为什么会这样。解决此问题的最佳方法是什么?如果我可以在后台运行刷新,这样它就不会阻塞 GUI,那也很好。

也许调用 run 并将秒数传递到 1 以便计时器可以更快地触发它?

4

1 回答 1

4

不要使用 a Timer,而是将另一个Event对象与超时结合使用。然后,您可以在按钮回调中设置该事件。以下代码说明了这一点(我已删除您的取消代码以使其简短):

import threading

class MyThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.sleep_event = threading.Event()
        self.damon = True

    def run(self):
        while True:
            self.sleep_event.clear()
            self.sleep_event.wait(60)
            threading.Thread(target=self._run).start()

    def _run(self):
        print "run"

my_thread = MyThread()
my_thread.start()

while True:
    raw_input("Hit ENTER to force execution\n")
    my_thread.sleep_event.set()

默认情况下,“运行”将每 60 秒打印一次。如果您按 ENTER 将立即打印,然后在 60 秒后再次打印,依此类推。

于 2011-12-18T22:57:23.657 回答