代码:
from threading import Timer
import time
def hello():
print "hello"
a=Timer(3,hello,())
a.start()
time.sleep(4)
a.start()
运行此脚本后,我收到错误:RuntimeError: threads can only be started once
那么我该如何处理这个错误呢。我想不止一次启动计时器。
答案 0 :(得分:4)
threading.Timer
继承threading.Thread
。线程对象不可重用。您可以为每个呼叫创建Timer
个实例。
from threading import Timer
import time
class RepeatableTimer(object):
def __init__(self, interval, function, args=[], kwargs={}):
self._interval = interval
self._function = function
self._args = args
self._kwargs = kwargs
def start(self):
t = Timer(self._interval, self._function, *self._args, **self._kwargs)
t.start()
def hello():
print "hello"
a=RepeatableTimer(3,hello,())
a.start()
time.sleep(4)
a.start()
答案 1 :(得分:0)
由于我每次烘烤cookie时都会启动烤箱定时器,因此我很惊讶地看到python的定时器只是一次性的。 也就是说,我共享一个小型计时器类,该类在 start 方法上提供了更多选项:
实施:
from threading import Timer, Lock
class TimerEx(object):
"""
A reusable thread safe timer implementation
"""
def __init__(self, interval_sec, function, *args, **kwargs):
"""
Create a timer object which can be restarted
:param interval_sec: The timer interval in seconds
:param function: The user function timer should call once elapsed
:param args: The user function arguments array (optional)
:param kwargs: The user function named arguments (optional)
"""
self._interval_sec = interval_sec
self._function = function
self._args = args
self._kwargs = kwargs
# Locking is needed since the '_timer' object might be replaced in a different thread
self._timer_lock = Lock()
self._timer = None
def start(self, restart_if_alive=True):
"""
Starts the timer and returns this object [e.g. my_timer = TimerEx(10, my_func).start()]
:param restart_if_alive: 'True' to start a new timer if current one is still alive
:return: This timer object (i.e. self)
"""
with self._timer_lock:
# Current timer still running
if self._timer is not None:
if not restart_if_alive:
# Keep the current timer
return self
# Cancel the current timer
self._timer.cancel()
# Create new timer
self._timer = Timer(self._interval_sec, self.__internal_call)
self._timer.start()
# Return this object to allow single line timer start
return self
def cancel(self):
"""
Cancels the current timer if alive
"""
with self._timer_lock:
if self._timer is not None:
self._timer.cancel()
self._timer = None
def is_alive(self):
"""
:return: True if current timer is alive (i.e not elapsed yet)
"""
with self._timer_lock:
if self._timer is not None:
return self._timer.is_alive()
return False
def __internal_call(self):
# Release timer object
with self._timer_lock:
self._timer = None
# Call the user defined function
self._function(*self._args, **self._kwargs)
以下是一个示例:
from time import sleep
def my_func(msg):
print(msg)
my_timer = TimerEx(interval_sec=5, function=my_func, msg="Here is my message").start()
sleep(10)
my_timer.start()
sleep(10)
注意::我使用的是python 3.7,所以我不确定100%可以在python 2上使用