我最近发表了一篇question关于如何在Python中推迟函数的执行(相当于Javascript setTimeout
)的文章,结果发现这是一个使用threading.Timer
的简单任务(好吧,只要函数不与其他代码共享状态,但这会在任何事件驱动环境中产生问题)。
现在我正努力做得更好,并模仿setInterval
。对于那些不熟悉Javascript的人,setInterval
允许每隔x秒重复调用一个函数,而不阻塞其他代码的执行。我已经创建了这个示例decorator:
import time, threading
def setInterval(interval, times = -1):
# This will be the actual decorator,
# with fixed interval and times parameter
def outer_wrap(function):
# This will be the function to be
# called
def wrap(*args, **kwargs):
# This is another function to be executed
# in a different thread to simulate setInterval
def inner_wrap():
i = 0
while i != times:
time.sleep(interval)
function(*args, **kwargs)
i += 1
threading.Timer(0, inner_wrap).start()
return wrap
return outer_wrap
使用如下
@setInterval(1, 3)
def foo(a):
print(a)
foo('bar')
# Will print 'bar' 3 times with 1 second delays
在我看来,一切都很顺利。我的问题是
sys.exit()
也不会停止它,也不会命中Ctrl+c
。阻止它的唯一方法是从外部终止python进程。我希望能够从主线程发送一个停止回调的信号。但我是一个线程初学者-我如何在它们之间进行通信?编辑如果有人想知道,这是decorator的最终版本,感谢jd的帮助
import threading
def setInterval(interval, times = -1):
# This will be the actual decorator,
# with fixed interval and times parameter
def outer_wrap(function):
# This will be the function to be
# called
def wrap(*args, **kwargs):
stop = threading.Event()
# This is another function to be executed
# in a different thread to simulate setInterval
def inner_wrap():
i = 0
while i != times and not stop.isSet():
stop.wait(interval)
function(*args, **kwargs)
i += 1
t = threading.Timer(0, inner_wrap)
t.daemon = True
t.start()
return stop
return wrap
return outer_wrap
它可以用于固定数量的重复,如上所述
@setInterval(1, 3)
def foo(a):
print(a)
foo('bar')
# Will print 'bar' 3 times with 1 second delays
或者可以让它一直运行直到收到停止信号
import time
@setInterval(1)
def foo(a):
print(a)
stopper = foo('bar')
time.sleep(5)
stopper.set()
# It will stop here, after printing 'bar' 5 times.
也许这是python中最简单的setInterval等价物:
我看你的解决办法不错。
有几种与线程通信的方法。要命令线程停止,可以使用
threading.Event()
,它有一个wait()
方法,您可以使用该方法而不是time.sleep()
。要使线程在程序终止时退出,请在调用
start()
之前将其daemon
属性设置为True
。这也适用于Timer()
对象,因为它们是threading.Thread
的子类。见http://docs.python.org/library/threading.html#threading.Thread.daemon也许更简单的是使用递归调用计时器:
atexit
允许使用CTRL-C发出停止信号相关问题 更多 >
编程相关推荐