65

Pythonで60秒ごとに関数を実行したいのですが、その間ブロックされたくありません。

どうすれば非同期で実行できますか?

import threading
import time

def f():
    print("hello world")
    threading.Timer(3, f).start()

if __name__ == '__main__':
    f()    
    time.sleep(20)

このコードでは、関数fは20秒のtime.time内で3秒ごとに実行されます。最後にエラーが発生しますが、これはthreading.timerがキャンセルされていないためだと思います。

どうすればキャンセルできますか?

前もって感謝します!

4

8 に答える 8

105

threading.Timerクラスを試すことができます:http://docs.python.org/library/threading.html#timer-objects

import threading

def f(f_stop):
    # do something here ...
    if not f_stop.is_set():
        # call f() again in 60 seconds
        threading.Timer(60, f, [f_stop]).start()

f_stop = threading.Event()
# start calling f now and every 60 sec thereafter
f(f_stop)

# stop the thread when needed
#f_stop.set()
于 2010-02-08T16:43:17.773 に答える
3

最も簡単な方法は、60秒ごとに何かを実行するバックグラウンドスレッドを作成することです。簡単な実装は次のとおりです。

class BackgroundTimer(Thread):   
   def run(self):
      while 1:
        Time.sleep(60)
        # do something


# ... SNIP ...
# Inside your main thread
# ... SNIP ...

timer = BackgroundTimer()
timer.start()

明らかに、これは「何かをする」のに時間がかかる場合は、睡眠ステートメントでそれに対応する必要があります。しかし、これは良い近似として役立ちます。

于 2010-02-08T16:44:12.110 に答える
3

私はググって、特定のイベント を待つことを可能にするPython circuit Framework を見つけました。

回路の.callEvent(self, event, *channels)メソッドには、起動および応答までサスペンド機能が含まれています。ドキュメントには次のように記載されています。

指定されたチャネルに指定されたイベントを発生させ、ディスパッチされるまで実行を中断します。yieldこのメソッドは、ハンドラの最上位実行レベル (例: " ")への引数としてのみ呼び出すことができますyield self.callEvent(event)。イベントがディスパッチされるまで、メインループによって呼び出されるジェネレーターを効果的に作成して返します ( :func: を参照circuits.core.handlers.handler)。

私と同じくらい役に立つと思います:)
./よろしく

于 2013-08-05T12:18:21.923 に答える
2

それは、その間に実際に何をしたいかによって異なります。スレッドは、最も一般的であり、最も好ましくない方法です。Queue.Queueスレッドを使用するときは、スレッドの問題に注意する必要があります: すべての (Python 以外の) コードが複数のスレッドから同時にアクセスできるわけではありません。スレッド間の通信は、 のようなスレッドセーフなデータ構造を使用して行う必要があります。スレッドを外部から実行し、スレッドがまだ実行されている間にプログラムを終了すると、インタープリターがハングしたり、誤ったトレースバックが発生したりする可能性があります。

多くの場合、もっと簡単な方法があります。GUI プログラムでこれを行う場合は、GUI ライブラリのタイマーまたはイベント機能を使用します。すべての GUI にこれがあります。同様に、Twisted や別のサーバー プロセス モデルなどの別のイベント システムを使用している場合は、メイン イベント ループにフックして、関数を定期的に呼び出すようにする必要があります。非スレッド化アプローチでは、関数が保留中の間はプログラムがブロックされますが、関数呼び出し間ではブロックされません。

于 2010-02-08T16:51:45.417 に答える
1

単純なスリープループを配置する専用スレッドを作成しないのはなぜですか。

#!/usr/bin/env python
import time
while True:
   # Your code here
   time.sleep(60)
于 2010-02-08T16:42:52.060 に答える
1

メソッドを「オンザクロック」(たとえば、毎正時)に呼び出したい場合は、次のアイデアを、選択したスレッドメカニズムと統合できます。

import time

def wait(n):
    '''Wait until the next increment of n seconds'''
    x = time.time()
    time.sleep(n-(x%n))
    print(time.asctime())
于 2015-07-01T21:49:25.180 に答える
1

スレッドを繰り返し実行する正しい方法は次のとおりだと思います。

import threading
import time

def f():
    print("hello world")  # your code here
    myThread.run()

if __name__ == '__main__':
    myThread = threading.Timer(3, f)  # timer is set to 3 seconds
    myThread.start()
    time.sleep(10)  # it can be loop or other time consuming code here
    if myThread.is_alive():
        myThread.cancel()

このコードでは、関数 f が 10 秒の time.sleep(10) 内で 3 秒ごとに実行されます。最後に、スレッドの実行はキャンセルされます。

于 2017-10-06T09:10:15.930 に答える