rendered paste bodyfrom __future__ import with_statementfrom heapq import heappush, heappopfrom time import timefrom threading import Event, Lockimport Queueclass Sched: def __init__(self): self.heap = [] self.running = True self.update_event = Event() self.heap_lock = Lock() def add(self, delay, queue): """Add new execution queue""" with self.heap_lock: heappush(self.heap, (time() + delay, delay, queue)) self.update_event.set() def stop(self): self.running = False self.update_event.set() def tasks(self): """Produce events until stopped""" self.running = True while self.running: self.update_event.clear() if not len(self.heap): self.update_event.wait() with self.heap_lock: runtime, delay, queue = heappop(self.heap) if time() < runtime: with self.heap_lock: heappush(self.heap, (runtime, delay, queue)) self.update_event.wait(runtime - time()) else : try : task = queue.get_nowait() except Queue.Empty: pass else : yield task queue.task_done() with self.heap_lock: heappush(self.heap, (time() + delay, delay, queue)) def raced_tasks(self): """Produce events until stopped""" self.running = True while self.running: self.update_event.clear() if not len(self.heap): self.update_event.wait() runtime, delay, queue = checked_event = self.heap[0] now = time() if now < runtime: self.update_event.wait(runtime - now) else : runtime, delay, queue = event = heappop(self.heap) # assure event was not removed or altered after last look at self.heap[0] if event is checked_event: try : task = queue.get_nowait() except Queue.Empty: continue else : yield task queue.task_done() self.add(delay, queue)if __name__ == '__main__': s = Sched() half_sec_q = Queue.Queue() half_sec_q.put(lambda :'foo') half_sec_q.put(lambda :'bar') s.add(0.5, half_sec_q) two_sec_q = Queue.Queue() two_sec_q.put(lambda :'baz') s.add(2, two_sec_q) three_sec_q = Queue.Queue() three_sec_q.put(s.stop) s.add(3, three_sec_q) print time() for value in s.tasks(): print time(), value()