特定の時間までカウントダウンするメソッドを作成しようとしていますが、再起動コマンドが指定されない限り、タスクを実行します。しかし、私はPython threading.Timer
クラスを使用すると、タイマーをキャンセルできます。
import threading
def countdown(action):
def printText():
print 'hello!'
t = threading.Timer(5.0, printText)
if (action == 'reset'):
t.cancel()
t.start()
私は上記のコードが何らかの形で間違っていることを知っています。ここでいくつかの親切なガイダンスをいただければ幸いです。
タイマーを開始した後、キャンセルメソッドを呼び出します。
import time
import threading
def hello():
print "hello, world"
time.sleep(2)
t = threading.Timer(3.0, hello)
t.start()
var = 'something'
if var == 'something':
t.cancel()
Timerを使用する代わりに、 Thread でwhileループを使用することを検討できます。
ニコラウス・グラドワールの answer から別の質問に割り当てられた例を次に示します。
import threading
import time
class TimerClass(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
self.count = 10
def run(self):
while self.count > 0 and not self.event.is_set():
print self.count
self.count -= 1
self.event.wait(1)
def stop(self):
self.event.set()
tmr = TimerClass()
tmr.start()
time.sleep(3)
tmr.stop()
正しく理解できるかどうかわかりません。この例のようなものを書きたいですか?
>>> import threading
>>> t = None
>>>
>>> def sayHello():
... global t
... print "Hello!"
... t = threading.Timer(0.5, sayHello)
... t.start()
...
>>> sayHello()
Hello!
Hello!
Hello!
Hello!
Hello!
>>> t.cancel()
>>>
threading.Timer
class doesにはcancel
メソッドがあり、threadをキャンセルしませんが、タイマーの実際の起動を停止します。実際に起こるのは、cancel
メソッドがthreading.Event
、およびスレッドが実際にthreading.Timer
は、待機が完了した後、実際にコールバックを実行する前に、そのイベントをチェックします。
とは言っても、タイマーは通常実装されますwithoutそれぞれに個別のスレッドを使用します。それを行う最善の方法は、プログラムが実際に何を行っているか(このタイマーを待っている間)によって異なりますが、GUIやネットワークフレームワークなど、イベントループのあるものはすべて、イベントループにフックされるタイマーを要求する方法があります。
上記の投稿に触発されました。 Pythonでのタイマーのキャンセルとリセット。スレッドを使用します。
機能:開始、停止、再起動、コールバック関数。
入力:タイムアウト、sleep_chunk値、およびcallback_function。
他のプログラムでこのクラスを使用または継承できます。コールバック関数に引数を渡すこともできます。
タイマーも途中で応答する必要があります。完全な睡眠時間の完了後だけではありません。したがって、1回の完全なスリープを使用する代わりに、小さなスリープチャンクを使用し、ループ内でイベントオブジェクトをチェックし続けました。
import threading
import time
class TimerThread(threading.Thread):
def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
threading.Thread.__init__(self)
self.timeout = timeout
self.sleep_chunk = sleep_chunk
if callback == None:
self.callback = None
else:
self.callback = callback
self.callback_args = args
self.terminate_event = threading.Event()
self.start_event = threading.Event()
self.reset_event = threading.Event()
self.count = self.timeout/self.sleep_chunk
def run(self):
while not self.terminate_event.is_set():
while self.count > 0 and self.start_event.is_set():
# print self.count
# time.sleep(self.sleep_chunk)
# if self.reset_event.is_set():
if self.reset_event.wait(self.sleep_chunk): # wait for a small chunk of timeout
self.reset_event.clear()
self.count = self.timeout/self.sleep_chunk # reset
self.count -= 1
if self.count <= 0:
self.start_event.clear()
#print 'timeout. calling function...'
self.callback(*self.callback_args)
self.count = self.timeout/self.sleep_chunk #reset
def start_timer(self):
self.start_event.set()
def stop_timer(self):
self.start_event.clear()
self.count = self.timeout / self.sleep_chunk # reset
def restart_timer(self):
# reset only if timer is running. otherwise start timer afresh
if self.start_event.is_set():
self.reset_event.set()
else:
self.start_event.set()
def terminate(self):
self.terminate_event.set()
#=================================================================
def my_callback_function():
print 'timeout, do this...'
timeout = 6 # sec
sleep_chunk = .25 # sec
tmr = TimerThread(timeout, sleep_chunk, my_callback_function)
tmr.start()
quit = '0'
while True:
quit = raw_input("Proceed or quit: ")
if quit == 'q':
tmr.terminate()
tmr.join()
break
tmr.start_timer()
if raw_input("Stop ? : ") == 's':
tmr.stop_timer()
if raw_input("Restart ? : ") == 'r':
tmr.restart_timer()