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

アプリのブートストラップでスレッドを開始し、それらをいくつかのリストに保存して、終了する前にキャンセルします。これは完璧に機能します。

しかし、現在実行されていない場合は、スレッドの1つを強制的に実行し、実行されるまで一定時間待機しない更新ボタンを追加したいと思います。

bool var を MyThread に追加して、スレッドが実行されているかどうかを示し (_run の前に設定し、完了時にリセット)、実行していない場合は MyThread._run() を呼び出すだけでそれを実行しようとしましたが、それによりアプリがunresponsive および _run タスクが実行を終了しないようにします。

なぜこれが起こるのかわかりません。この問題を解決する最善の方法は何ですか? GUIをブロックしないように、バックグラウンドで更新を実行できれば問題ありません。

たぶん、run を呼び出して秒数を 1 に渡して、タイマーがより早くトリガーできるようにしますか?

4

1 に答える 1

4

を使用する代わりに、タイムアウトと組み合わせて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()

デフォルトでは、「ru​​n」は 60 秒ごとに出力されます。ENTER を押すと、すぐに印刷され、60 秒後に再び印刷されます。

于 2011-12-18T22:57:23.657 に答える