这个回答有两个建议 - 我的第一个建议和我在第一个建议之后发现的另一个建议。
sched
我猜您正在寻找
sched
模块。
编辑: 在阅读了我的简短建议后感觉不太有用,所以我决定测试一下
sched
模块,看它是否能按照我的建议工作。这是我的测试: 我将使用单个线程来运行它,大致如下:
class SchedulingThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.scheduler = sched.scheduler(time.time, time.sleep)
self.queue = []
self.queue_lock = threading.Lock()
self.scheduler.enter(1, 1, self._schedule_in_scheduler, ())
def run(self):
self.scheduler.run()
def schedule(self, function, delay):
with self.queue_lock:
self.queue.append((delay, 1, function, ()))
def _schedule_in_scheduler(self):
with self.queue_lock:
for event in self.queue:
self.scheduler.enter(*event)
print "Registerd event", event
self.queue = []
self.scheduler.enter(1, 1, self._schedule_in_scheduler, ())
首先,我会创建一个线程类,该类具有自己的调度器和队列。至少在调度器中注册一个事件:用于调用从队列中调度事件的方法。
class SchedulingThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.scheduler = sched.scheduler(time.time, time.sleep)
self.queue = []
self.queue_lock = threading.Lock()
self.scheduler.enter(1, 1, self._schedule_in_scheduler, ())
从队列中安排事件的方法将锁定队列,安排每个事件,清空队列并再次安排自己,以便在未来的某个时间查找新事件。请注意,查找新事件的间隔很短(一秒),您可以更改它:
def _schedule_in_scheduler(self):
with self.queue_lock:
for event in self.queue:
self.scheduler.enter(*event)
print "Registerd event", event
self.queue = []
self.scheduler.enter(1, 1, self._schedule_in_scheduler, ())
该类还应该有一个用于安排用户事件的方法。自然而然,在更新队列时,这个方法应该锁定队列:
def schedule(self, function, delay):
with self.queue_lock:
self.queue.append((delay, 1, function, ()))
最后,该类应调用调度程序的主方法:
def run(self):
self.scheduler.run()
以下是一个使用示例:
def print_time():
print "scheduled:", time.time()
if __name__ == "__main__":
st = SchedulingThread()
st.start()
st.schedule(print_time, 10)
while True:
print "main thread:", time.time()
time.sleep(5)
st.join()
在我的机器上它的输出是:
$ python schedthread.py
main thread: 1311089765.77
Registerd event (10, 1, <function print_time at 0x2f4bb0>, ())
main thread: 1311089770.77
main thread: 1311089775.77
scheduled: 1311089776.77
main thread: 1311089780.77
main thread: 1311089785.77
这段代码只是一个快速且简陋的示例,也许需要一些修改。然而,我必须承认,sched
模块让我有点着迷,所以我建议使用它。你可能还想寻找其他建议 :)
APScheduler
在谷歌上寻找像我发布的解决方案这样的解决方案时,我发现了这个令人惊叹的APScheduler模块。它非常实用和有用,我敢打赌它就是你的解决方案。如果使用这个模块,我的前面那个示例会变得更简单:
from apscheduler.scheduler import Scheduler
import time
sch = Scheduler()
sch.start()
@sch.interval_schedule(seconds=10)
def print_time():
print "scheduled:", time.time()
sch.unschedule_func(print_time)
while True:
print "main thread:", time.time()
time.sleep(5)
很不幸,我没有找到如何调度仅执行一次的事件,因此该函数应该取消调度。我打赌可以通过某些装饰器来解决这个问题。