可取消线程。Python中的计时器
我正在尝试编写一个方法,该方法将倒计时到给定的时间,除非给出重新启动命令,否则它将执行任务。但我不认为Python可取消线程。Python中的计时器,python,python-2.7,timer,python-multithreading,Python,Python 2.7,Timer,Python Multithreading,我正在尝试编写一个方法,该方法将倒计时到给定的时间,除非给出重新启动命令,否则它将执行任务。但我不认为Pythonthreading.Timer类允许计时器可以取消 import threading def countdown(action): def printText(): print 'hello!' t = threading.Timer(5.0, printText) if (action == 'reset'): t.can
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 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()
>>>
启动计时器后,将调用cancel方法:
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()
你可以考虑在A上使用while循环,而不是使用定时器。 以下是一个从尼古拉斯·格拉德沃尔(Nikolaus Gradwohl)到另一个问题的例子:
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()
threading.Timer
类有一个cancel
方法,虽然它不会取消线程,但它会阻止计时器实际启动。实际发生的情况是,cancel
方法设置了一个threading.Event
,而实际执行threading.Timer
的线程将在等待完成后和实际执行回调之前检查该事件
也就是说,计时器通常是在不使用单独线程的情况下实现的。最好的方法取决于你的程序实际在做什么(等待这个计时器),但是任何带有事件循环的东西,比如GUI和网络框架,都有方法请求一个连接到事件循环的计时器。受上述文章启发。
Python中的可取消和重置计时器。它使用线程。功能:启动、停止、重启、回调功能。
输入:超时、睡眠块值和回调函数。
可以在任何其他程序中使用或继承此类。还可以将参数传递给回调函数。
计时器也应该在中间响应。不仅仅是在完全睡眠后。所以,不要使用一次完全睡眠,而是使用小块睡眠并不断检查循环中的事件对象
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()
导入线程
导入时间
类TimerThread(threading.Thread):
def uuu init uuuu(self,timeout=3,sleep\u chunk=0.25,callback=None,*args):
threading.Thread.\uuuuu init\uuuuuu(自)
self.timeout=超时
self.sleep\u chunk=睡眠块
如果回调==无:
self.callback=None
其他:
self.callback=回调
self.callback_args=args
self.terminate\u event=threading.event()
self.start\u event=threading.event()
self.reset_event=threading.event()
self.count=self.timeout/self.sleep\u块
def运行(自):
而不是自身。终止事件。是否设置了:
当self.count>0且self.start\u event.is\u set()时:
#打印自计数
#时间.睡眠(self.sleep\u块)
#如果self.reset\u event.is\u set():
如果self.reset_event.wait(self.sleep_chunk):#等待一小段超时
self.reset_事件.clear()
self.count=self.timeout/self.sleep_chunk#重置
self.count-=1
如果self.count我不确定是否是最好的选择,但对我来说是这样的:
t=timer_mgr(…)附加到列表“timers.append(t)”中,然后在创建完之后,您可以调用:
for tm in timers:#threading.enumerate():
print "********", tm.cancel()
我的timer_mgr()类是:
class timer_mgr():
def __init__(self, st, t, hFunction, id, name):
self.is_list = (type(st) is list)
self.st = st
self.t = t
self.id = id
self.hFunction = hFunction
self.thread = threading.Timer(t, self.handle_function, [id])
self.thread.name = name
def handle_function(self, id):
if self.is_list:
print "run_at_time:", datetime.now()
self.hFunction(id)
dt = schedule_fixed_times(datetime.now(), self.st)
print "next:", dt
self.t = (dt-datetime.now()).total_seconds()
else:
self.t = self.st
print "run_every", self.t, datetime.now()
self.hFunction(id)
self.thread = threading.Timer(self.t, self.handle_function, [id])
self.thread.start()
def start(self):
self.thread.start()
def cancel(self):
self.thread.cancel()
请解释为什么您认为计时while循环比线程计时器更好。@我提供了另一种打印倒计时的方法。对我来说很有用。虽然我使用while而不是self.event.wait(1)每秒执行一次,而不是使用count变量,但这几乎很好。如果您的程序没有立即终止就好了,只需一声“您好”,一点延迟都没有您必须根据某些条件将t.cancel()
合并到sayHello()
函数中,例如如果计数器==10:t.cancel()
。那就有意义了。对不起。即使那样也不好。如果在调用sayHello(0)
后添加任何代码,它将在计时器测试完成之前执行!(您可以自己尝试,例如在代码末尾添加print“Done”
)如果我有classTimerThread
和classApplication
,并且我的回调函数在Application中,我如何调用TimerThread并在self上设置回调?我已经尝试了你的代码,但它从来没有击中回调。